站内搜索: 请输入搜索关键词

当前页面: 开发资料首页Netbeans 专题NetBeans IDE 4.1/5.0 Profiler 教程

NetBeans IDE 4.1/5.0 Profiler 教程

摘要: NetBeans IDE 4.1/5.0 Profiler 教程 作者及整理人: Gregg Sporar '); //--> Gregg Sporar Gregg Sporar 、 Ruth Kus...
NetBeans IDE 4.1/5.0 Profiler 教程

本文章旨在介绍配合使用 NetBeans Profiler v5.0 或 Profiler Milestone 8 的内容。如果您使用的是 Milestone 5,请使用此版本。如果您使用的是 Milestone 6,请使用此版本

预计持续时间:50 分钟

NetBeans Profiler 是一个功能强大的工具,它提供了有关应用程序运行时行为的重要信息。NetBeans Profiler 产生的开销相对来说较小,它可以跟踪线程状态、CPU 性能和内存使用情况。本教程将向您介绍如何使用 NetBeans Profiler 来完成以下操作:

先决条件

本教程假定您已经具有了一些基本的 Java 编程和 NetBeans IDE 使用经验。

教程所需的软件:

本文档使用的表示法

    • 本文档使用 <tutorial_root> 来表示解压缩此教程的 zip 文件所在的目录。此教程的 zip 文件的名称为 profilertutorial.zip
    • 将教程 zip 文件解压缩到 <tutorial_root> 目录时,系统会创建一个名为 netbeansprofiler 的子目录。例如,在 Windows 操作系统中,如果已将教程 zip 文件解压缩到驱动器 E:\ 的根目录中,则系统会创建 E:\netbeansprofiler 子目录。在 Solaris/Linux 操作系统中,如果已将教程 zip 文件解压缩到 /home/username 目录中,则系统会创建 /home/username/netbeansprofiler 子目录。

教程练习

参考资源:



练习 0:安装并配置教程环境

在开始学习教程之前,请先检查以下内容:

  1. 启动 NetBeans IDE,并确认 IDE 已打开。通过选择 Profile > Help > About Profiler...,验证是否安装了 NetBeans Profiler
    • 在 Windows 操作系统中,双击 NetBeans IDE 图标
    • 在 Solaris/Linux 操作系统中,打开终端窗口,然后键入 <NETBEANS_HOME>/bin/netbeans
  2. 仅限 NetBeans IDE v4.1:安装所需的修补程序。
    1. Tools 菜单选择 Update Center,以访问 NetBeans 更新中心。
    2. 确保选中了 NetBeans Hotfix Update Center,然后单击 Next 按钮。建立连接后,将显示一个更新列表。
    3. 在 NetBeans Hotfix Update Center 条目下,选择 "NetBeans Profiler (J2EE Projects - Tomcat5 Support)"。该操作还将自动选择 "Tomcat 5 Server" 条目。
    4. 单击 Next(下一步) 按钮,并按照说明进行操作以便 IDE 可以安装这些修补程序。




练习 1:监视 Swing 应用程序中的线程状态(15 分钟)

本练习的学习目的:

在本练习中,您将学习如何使用 NetBeans Profiler 监视 J2SE 应用程序中的线程状态。这样,您就可以诊断样例应用程序中的性能问题。

背景信息:

Swing 为 J2SE 应用程序提供了图形用户界面组件。Swing 库会使用到多个线程,利用 NetBeans Profiler 这一功能强大的工具,您可以分析出每个线程所花费的处理时间,从而利用这些分析信息来解决性能问题。

执行步骤:

  1. 选择 File > Open Project。找到 <tutorial_root>/netbeansprofiler/exercises 文件夹。选择 exercise1 文件夹,然后单击 Open Project Folder 按钮。
  2. 在 Projects() 窗口中,右键单击 exercise1 条目并选择 Clean and Build Project。然后,再次右键单击 exercise1 条目并选择 Run Project。此时,将显示该程序的窗口,如下所示。


  3. 将 Seconds Before Notification 设置为 30。
  4. 单击 Start! 按钮。请注意,该程序无法正确地刷新屏幕。
  5. 单击 Exit 按钮。请注意,该程序根本不会作出响应。
  6. 将另一个窗口放在该窗口的某一部分上,以遮挡该窗口的视图。当移开另一个窗口时,您会注意到样例应用程序没有相应地刷新其窗口。如下面的示例所示。


  7. 30 秒后,最终将显示一个消息框,如下所示。单击消息框上的 OK 按钮。


  8. 应用程序窗口将再次开始响应。单击 Exit 按钮将其关闭。
  9. 选择 Profile > Profile Main Project
  10. 如果出现一个对话框,询问您是否允许修改项目生成脚本,请单击 OK。如下面的示例所示。


  11. 将会显示 Profile 对话框。单击占据较大区域的 Monitor Application 按钮。
  12. 应选中 Enable Threads Monitoring 复选框。
  13. 单击 Run 按钮。如果显示一个对话框,指示您必须先收集 Profiler 的校准信息,请单击 OK 按钮。如下面的示例所示。

    选择 Profile > Advanced Commands > Run Profiler Calibration。完成校准后,Profiler 会显示一个对话框,请单击 OK 按钮。如下面的示例所示。

    要进行性能分析,请返回至上面的第 9 步。

  14. 完成上述步骤后,将启动该应用程序,并且 IDE 会显示 Profiler 控制面板,如下所示。


  15. Profiler 将在其主窗口中显示线程状态,如下面的示例所示。


    它使用颜色编码来显示线程状态。

    • 绿色:线程正在运行或准备运行。
    • 紫色:线程正在调用 Thread.sleep(),处于休眠状态。
    • 黄色:线程正在调用 Object.wait(),处于等待状态。
    • 红色:线程在尝试访问同步的块或方法时受阻。

  16. 找到样例 Swing 应用程序的窗口(NetBeans IDE 窗口可能在其上面)。单击样例应用程序中的 Start! 按钮,同时监视标记为 AWT-EventQueue-0 的线程所发生的变化。它将变为绿色并持续这种状态整整 30 秒钟,如以下样例所示。

    此图形显示了应用程序没有响应的原因。标记为 AWT-EventQueue-0 的线程是 Swing 用来处理窗口事件的事件分发线程 (Event Dispatch Thread, EDT)。在正常运行的 Swing 应用程序中,EDT 的大部分时间处于等待状态而运行的时间却很少,因为它只有在分发事件时才会运行很短的一段时间。但是,如果应用程序中的事件处理程序未立即返回,则程序将停止响应,就像在此示例中一样。

  17. 30 秒后,屏幕将显示应用程序的消息框。找到该消息框(NetBeans IDE 窗口可能在其上面)并单击 OK 按钮。然后,单击样例应用程序的 Exit 按钮,将其关闭。
  18. Projects 窗口与 Profiler 控制面板共享同一个空间;单击 Projects 标签将会显示 Projects 窗口。
  19. 在 Projects 窗口中,双击 exercise1 条目以将其展开,然后展开 Source Packages 和 profilingthreads 条目。右键单击 DisplayForm.java 条目并选择 Open
  20. 在包含 DisplayForm.java 的编辑器窗口中,取消第 132 行至第 157 行的代码块注释。提示:如果未将编辑器配置为显示行号,请选择 View > Show Line Numbers
  21. 在包含 DisplayForm.java 的编辑器窗口中,取消(或注释掉)第 122 行到第 128 行的代码块注释。下图突出显示了取消注释的代码块。


  22. 选择 File > Save。您刚才删除了未正确使用 EDT 的代码,并利用了更稳定可靠的解决方案来替代它。现在,应用程序可以及时地作出响应。
  23. 选择 Build > Build Main Project(或按 F11 键)。
  24. 选择 Profile > Profile Main Project
  25. 将会显示 Profile 对话框。单击占据较大区域的 Monitor Application 按钮。
  26. 确保选中了 Enable Threads Monitoring。
  27. 单击 Run 按钮。
  28. 当显示样例程序时,单击 Start! 按钮。请注意,此时的性能分析线程图已经发生了变化,如以下示例所示。

    EDT 为黄色,应用程序创建的名为“Our SwingWorker #1”的线程为绿色。由于 EDT 不是用来执行耗时任务的,因此,按钮和其他程序控件仍保持响应的状态。

  29. 在样例程序中单击 Exit 按钮。
  30. 右键单击 Profiler 图形中的 AWT-EventQueue-0 线程,然后选择 Thread Details。Profiler 会显示一个饼图,表明了每种状态所花的时间;如以下示例所示。

    该图形可以帮助您判断程序在每个线程中所花费的时间是否恰当。上述示例是代码修复后的示例,因此,它显示了 EDT 在大部分时间中都处于等待状态的情形,这正好是该线程应具有的行为。

  31. 在 Projects 窗口中,右键单击 exercise1 条目,然后选择 Close Project

小结:

在本练习中,您学习了如何使用 Profiler 来启动应用程序,以及如何解释 Profiler 的线程信息图形,以此来跟踪 Swing 应用程序中的性能问题。

返回页首



练习 2:确定某个方法使用的 CPU 时间(15 分钟)

本练习的学习目的:

在本练习中,您将学习如何使用 Profiler 来确定某个应用程序的方法所花费的时间。

背景信息:

CPU 的性能问题通常与应用程序的特定功能有关。例如,在报告系统中,某个报告的运行速度可能比其他报告慢。只分析应用程序中出现性能问题的部分,可以大大减少 Profiler 产生的开销。在本练习中,您将使用 NetBeans Profiler 来检查 Web 应用程序中 CPU 的使用情况。在练习 3 中,我们仍然使用该样例 Web 应用程序来说明如何通过 Profiler 查找内存泄漏。

执行步骤:

  1. 选择 File > Open Project。找到 <tutorial_root>/netbeansprofiler/exercises 文件夹。选择 exercise2 文件夹,并确保选中 Open As Main Project。单击 Open Project Folder 按钮。
  2. 在 Projects 窗口中,单击 exercise2 条目,然后从菜单中选择 Build > Clean and Build Main Project
  3. 从菜单中选择 Profile > Profile Main Project。如果出现一个对话框,询问您是否允许修改项目生成脚本,请单击 OK。
  4. 将会显示 Select Profiling Task 对话框。
  5. 单击 Analyze Performance 按钮。
  6. 选择 Part of Application 单选按钮。然后,单击位于 Part of Application 单选按钮旁边的 Select 按钮。此时将显示 Specify Root Methods 窗口。
  7. 注意:下面的三个步骤仅适用于 Milestone 8。

  8. 在 Specify Root Methods 窗口中,单击 Add 按钮以添加要分析的根方法。将会显示 Select Method 窗口。
  9. 在 Select Methods 窗口中,单击 Select 按钮。Profiler 将显示 Go To Class 窗口。
  10. 在 Class Name 文本字段中输入 Per。等待 IDE 为您显示适用的类列表。选择 Performance 类。单击 Open 按钮打开其方法列表。

    注意:下面的两个步骤只适用于 Profiler v5.0。

  11. 在 Specify Root Methods(指定根方法) 窗口中,单击 Add From Project...按钮以添加要分析的根方法。将会显示 Select Methods 窗口。
  12. 在 Class Name 文本字段中,键入 demo.Performance,然后按 Enter 键。
  13. 返回页首



分析对象创建过程以查找内存泄漏(20 分钟)

本练习的学习目的:

作为练习 2 的后续练习,我们将在本练习中学习如何解释某些监视应用程序创建对象过程的 Profiler 图形。下面将显示一个内存泄漏示例。

执行步骤:

  1. 本练习是在练习 2 的基础上进行的,因此,请务必遵循练习 2 中的步骤。
  2. 从菜单中选择 Profile > Profile Main Project。如果出现一个对话框,询问您是否要停止当前的 Profiler 进程以启动新进程(如下所示),请单击 Yes 按钮继续执行。

    将会显示 Select Profiling Task 对话框。

  3. 在 Select Profiling Task 对话框中,单击占据较大区域的 Monitor Application 按钮。
  4. 单击 Run 按钮。IDE 将会左侧显示 Profiler 控制台。单击 按钮,或者选择 Profile > View > Telemetry Overview。NetBeans Profiler 将在底部的输出窗口中显示三个图形,如下所示。

    在左侧的图形中,红色的阴影部分表示分配的 JVM 堆大小。紫色的覆盖部分表示实际使用的堆空间大小。在上面的示例中,上次更新所分配的堆大小已超过了 20 MB。其中,实际用来保存 Java 对象的堆大小略大于 10 MB。

    右侧图形显示了 JVM 中的活动线程数。

    中间的图形显示了两种重要的堆统计信息。

    • 蓝线是 JVM 执行垃圾回收的时间占执行时间的百分比,它是以图形右侧上的 Y 轴为参照绘制的。JVM 执行垃圾回收所花的时间不能用来运行应用程序。因此,如果蓝线占据较大的百分比,则需要考虑调整 JVM,方法是:配置更大的堆大小(请参阅 -Xmx 参数文档),或者转换到不同的垃圾回收算法中。
    • 红线表示存活的生成数,它是以图形左侧的 Y 轴为参照进行绘制的。存活生成数是指 JVM 堆上所有 Java 对象不同生存期的数量,其中“生存期”被定义为对象存活时的垃圾回收次数。如果存活生成数的值较小,则表明堆上的大部分对象的存活时间基本相同。但是,如果存活生成数的值随着时间的变化而增长到一个很高的比率,则表明应用程序正在分配新的对象,同时保持对已分配的多个旧对象的引用。如果实际上不再需要这些旧对象,则应用程序正在浪费(或“泄漏”)内存。
  5. Profiler 可以对 CPU 性能或内存使用情况进行详细的分析(也称为测试),但不能同时进行这两种分析。要了解有关在 JVM 堆上分配对象以及执行对象的垃圾回收的详细信息,请修改 Profiler 的设置。单击 按钮,或者选择 Profile > Modify Profiling
  6. 单击 Analyze Memory Usage 按钮。
  7. 选择 Record both object creation and garbage collection 单选按钮。
  8. 选中 Record Stack Trace for Allocations 复选框。
  9. 单击 OK 按钮。
  10. 现在,您已经选择了分析内存使用情况,您需要运行应用程序以确定它是否有效地使用了内存。单击 Memory Leak 转至 MemoryLeak 演示页。
  11. 在 MemoryLeak 演示页上,单击 Start Leaking
  12. 请注意存活生成数图形中的峰值,如以下示例所示。这表明可能出现了内存泄漏。


  13. 选择 Profile > View > Live Results。Profiler 将显示 JVM 堆中分配的对象的动态视图。默认情况下,它将按每个类的所有实例使用的字节数进行排序。由于怀疑可能出现了内存泄漏,因此,请单击 Generations 列,按每个类的不同对象生存期数量对显示结果进行排序。下面显示了得到的显示结果示例。


    这些列提供了对象分配和内存使用情况信息。

    • Allocated Objects 是 Profiler 正在监视的对象数。在本示例中,共监视了 38 个 float[] 实例。默认情况下,该数字约为应用程序实际分配的对象数的 10%。通过只监视已创建对象的一部分,Profiler 可以显著地减少它在 JVM 中的开销,这样,应用程序就几乎可以按最快的速度运行了。
    • Live Objects 是仍在 JVM 堆中并因此占用内存的已分配对象数。
    • 两个 Live Bytes 列显示了活动对象所占用的堆内存量。一个列显示图形,另一个列显示文本。
    • Avg.Age 值是使用活动对象计算的。每个对象的生存期是它存活时的垃圾回收次数。生存期总和除以活动对象数得到的结果就是 Avg.Age。
    • Generations 值是使用 Live Object 计算的。与 Avg.Age 相同,对象生存期是它存活时的垃圾回收次数。Generations 值是活动对象的不同生存期数量。

  14. 随着程序继续运行,Profiler 将更新显示结果。请留意 float[]double[] 条目。请注意其生成数值是如何持续增加的。结果是,float[]double[] 在列表中持续上移。最终,它们会显示在列表的顶部,紧靠 java.util.HashMap$Entry(其生代数值也在不断增加)下方。随着应用程序继续运行,java.util.HashMap$Entryfloat[]double[] Generations 值持续增加,但任何其他类没有增加。如下面的示例所示。


  15. 要了解导致 Generations 值持续增加的原因,请选择 Profile > Take Snapshot of Collected Results。按 Generations 对显示结果进行排序。右键单击 double[] 条目,然后选择 Show Allocation Stack Traces。Profiler 将显示所有分配了一个或多个 double[] 对象的方法。如下面的示例所示。


    请注意,在分配了 double[] 对象的方法中,只有一个方法创建了具有较大 Generations 值的 double[] 对象。该方法是 run(),它位于具有相应名称 demo.memoryleak.LeakThread 的类中。

  16. 右键单击 run() 方法条目,然后选择 Go To Source...。Profiler 将显示源代码,如下所示。
    请注意,正在分配 double[]float[] 对象,并随后将其放在 HashMap 中。但一直并未删除它们,这意味着,HashMap 保留的引用将会妨碍 JVM 对这些对象进行垃圾回收。这是非常典型的 Java 内存泄漏:将对象放在 Map 中,然后就忘记处理它们了。由于本示例中使用的 Map 就是 HashMap,因此,关联的 java.util.HashMap$Entry 对象也出现了泄漏。
  17. 选择 Profile > Stop 来结束性能分析会话,或者单击 按钮。
  18. 在 Projects 窗口中,选择 exercise2 条目,然后从菜单中选择 File > Close Project

小结:

在本练习中,您学习了如何使用 Profiler 来监视应用程序创建对象的过程。您还看到了 Profiler 在应用程序出现内存泄漏时所提供的各种类型的分析指数。

返回页首


恭喜您!您已成功地完成了 NetBeans IDE 4.x Profiler 教程。






↑返回目录
前一篇: NetBeans Profiler 功能
后一篇: 使用 NetBeans IDE 5.0 开发 Struts Web 框架的快速入门指南