corner imagecorner image FeaturesPluginsDocs & SupportCommunityPartners

性能分析结果 - 内存使用情况

性能分析结果 - 内存使用情况

分析内存使用情况时,“性能分析结果”标签将显示有关对象分配和活动性的数据。选择以下性能分析任务时,将显示这些结果:

分析内存使用情况时,显示的性能分析结果取决于对下列选项的选择:

  • 记录对象创建和垃圾回收(对象活动性)

    此选项提供了有关仍处于活动状态的每种类型的对象数量的相关信息以及有关活动对象的数据。

  • 仅记录对象创建(对象分配)

    此选项提供了有关已分配对象的数量、类型和位置的相关信息。此性能分析模式是对象活动性性能分析的一个功能子集。提供两种模式的原因是,单纯针对对象分配而进行性能分析时,造成的性能影响和内存开销较小。

要打开“性能分析结果”标签,请单击 "Profiler" 窗口中的“实时结果”按钮 (实时结果)。

对象活动性结果

分析对象活动性时,“性能分析结果”标签中将显示以下信息(单击此处可查看对象活动性性能分析结果示例)。

  • 活动字节(图形)
  • 活动字节(数字)
  • 活动对象

    这是此时给定类的跟踪活动对象的大小和数量。跟踪的对象是所有分配对象的子集,将收集这些分配对象的栈跟踪,确定其大小并监视其活动状态。请参见此统计数据收集方法的详细信息。在对象分配性能分析中,建议只对一小部分对象(比如十分之一或二十分之一)进行跟踪,以便控制时间和空间开销。可以在“分析内存使用情况”命令对话框中更改跟踪的对象比例,也可以在执行定制内存性能分析时更改该比例。

  • 跟踪的已分配对象数

    这是跟踪的已分配对象的总数。

  • 平均对象生存期

    这是跟踪的该类活动对象的平均生存期。对象生存期是以该对象存活期间的垃圾回收 (Garbage Collection, GC) 次数进行测量的。使用年代式垃圾回收器(它是 HotSpot JVM 的缺省回收器)时,Profiler 目前无法区分部分(幼年)和完整垃圾回收。平均生存期是所有对象生存期之和除以对象数所得的结果。

  • 存活的年代数

    对于特定类的对象的方法,测量其存活的年代数是以一种复杂的方式进行计算的。本质上,它表示类对象的各个对象生存期的总数。如果某个类的这一数字持续稳步增长,通常表明出现了内存泄漏。这是因为内存泄漏(或至少是最危险的一种内存泄漏)是这样一种情况:一直为某个类分配对象,但至多回收部分对象。通过获得泄漏类的反向调用图形,可以确定哪个分配位置存活的年代数最多,即哪个分配位置生成了大部分或全部泄漏对象。了解分配对象的位置往往有助于查明内存泄漏的原因。

  • 分配的对象总数

    此类的已分配对象总数。此数字便是执行对象分配性能分析时得到的数字,它表示给定类实际曾经分配的对象总数。

通过单击相应的列标题或使用本地弹出式菜单,可以按任何上述数字对类进行排序。也可以选择停止分析某些类。

停止分析某些类

在分析对象活动性时,可以限制所分析的类。您可以右键单击某个类以打开上下文菜单,其中包含用于停止分析选定类的选项,或者用于停止分析选定类下面列出的所有类的选项。在分析包含大量类的应用程序并已确定您需要注意的类(例如,生存期最长的类或泄漏类)时,此选项非常有用。在这种情况下,通过停止分析所有其他类来避免不必要的运行时开销(可能很高)是很有意义的。

Profiler 如何跟踪对象活动性

Profiler 会一直并且只跟踪已注册分配的对象的活动性状态。也就是说,它不像某些其他工具那样生成堆快照,而是在内部将 Java WeakReference 与它已注册分配的对象相关联。如果在程序执行过程中启动对象活动性分析,或在性能分析处于活动状态时调用“性能分析”>“重置收集的结果”重置收集的结果,则很可能无法看到目标 VM 堆上的所有活动对象。然而,与解决对象活动性性能分析最重要问题 - 一直分配过多的对象和内存泄漏 - 相比,这并不是一个严重问题。在上述情况下,了解应用程序目前分配的对象数和作为垃圾回收的对象数比了解很久以前(甚至是在应用程序启动时)分配的对象数更为重要。

对象分配结果

分析对象分配时,“性能分析结果”标签显示一个类列表(包括数组类),列出了发出分析命令后分配的对象实例的总大小和数量(单击此处可查看对象分配性能分析结果示例)。

在启用对象分配性能分析后,便会对目标 JVM 当前装入的所有类(及每个装入的新类)进行性能分析以生成有关对象分配的信息。Profiler 提供的对象分配数是准确数字,尽管缺省情况下对象总大小和反向调用图形都是以统计方式获得的。有关 Profiler 如何执行此操作的详细信息,请参见内存性能分析中的不完全统计数据收集。

使用结果:泄漏应用程序

以下是一个存在泄漏的应用程序,初步确定 String 类的实例存在泄漏。这是因为,尽管此类对象本身的数量相对较小,但其存活的年代数远大于其他类型对象的年代数,而且这一数字还在持续增长:

内存泄漏图形

随后,我们查明代码中存在泄漏的 String 实例(与“健康”String 实例相对)的位置(此位置的存活年代数同样远大于其他位置的存活年代数)。

内存泄漏栈

另请参见

 

 
 
loading
Please Confirm