IBM 的 Java 诊断,第 2 部分: 使用 Extensible Verbose Toolkit 进行垃圾收集

提高应用程序性能、优化垃圾收集以及发现应用程序问题

Extensible Verbose Toolkit 是 IBM 的新工具®,其设计目标为帮助诊断和 分析与内存有关的 Java™ 性能问题 。 本文是四篇系列文章的第二篇,介绍如何获得和使用该套件, 并演示如何使用它来快速诊断某些常见的问题。

Dr. Holly Cummins (cumminsh@uk.ibm.com), 软件工程师, Java Technology Center, IBM

Dr. Holly CumminsHolly Cummins 是 IBM United Kingdom Java 技术中心的一名开发人员,而且还是 EVTK 的创作者。她在 IBM 工作了六年时间,她具有量子计算方面的博士学位以及软件工程的硕士学位。她非常喜欢蓝莓、格鲁耶尔芝士、晦涩的排版语言和不实用的鞋类。她非常不善于管理家务,厨房餐桌堆得像一座小山。



2007 年 11 月 02 日

鉴于以下这些原因,您可能需要仔细查看应用程序中的垃圾收集 (GC)。您可能关心应用程序的内存使用模式:是否使用了太多内存?是否发生内存泄露?内存使用情况是否能长期维持? 您还可能对如何提高应用程序执行速度感兴趣。 垃圾收集对应用程序的性能具有很大影响。很多人都知道,配置不佳的 GC 会使用 大量资源,而且还会降低应用程序的速度。但反过来也正确: 明智地选择垃圾收集参数实际上会使应用程序运行速度更快。

在周期较短的 Java 应用程序或性能不是 非常重要的应用程序中, 可以恰当地忽略 GC。在其他情况下,该工具可以从详细的 GC 日志中 更加轻松地获得所需的信息。 该工具可以显示堆中正在发生的变化,从而 更加容易确定模式, 它它 甚至可以为您指出某些模式并且给出调整建议。

EVTK 属于 IBM 的新工具套件,它分析详细的 GC 日志以帮助提供对内存管理问题的深入分析。在本文中,您将了解 EVTK 的功能并查看 EVTK 可以帮助您诊断内存问题的示例场景。

EVTK 可以处理所有版本为 1.4.2 或更高版本的 IBM JRE 日志。还可以 实时查看 IBM WebSphere® 中的日志。借助这种工具,您可以同时对比多个日志、放大日志的特定区域、 筛选数据以及在单位范围内显示。 EVTK 显示示例如图 1 所示:

图 1. EVTK 显示示例
EVTK 显示示例

启用详细的 GC 日志记录

如果想生成用于分析的日志,必须对应用程序启用详细的 GC 日志记录。 也可以通过 -verbose:GC 虚拟 机 (VM) 标记或通过版本为 5.0 或更高版本的 IBM VM 的 -XverboseGClog:file 命令。其中,file 是您所选择的日志文件的名称。-XverboseGClog 选项可用时,首选该选项。 详细 GC 通常对应用程序性能的影响比较小。

下载和安装 EVTK

关于 IBM Support Assistant

IBM Support Assistant 是免费的软件适用性工作平台,它帮助您解决 IBM 软件产品的问题。ISA 具有搜索工具,该工具跨越很多 IBM 文档并对结果进行分类以便进行查看。

它还提供产品信息功能,具有到产品支持和主页、故障排除指南和各种论坛和新闻组的链接。ISA 的服务功能可以从您的桌面收集信息并且可以轻松为 IBM 创建一个问题报告。

ISA 的工具工作平台提供问题确定工具,帮助解决 IBM 产品的问题。这些工具将不断更新,并且使您能够在桌面上运行故障排除和诊断工具。请参阅 参考资料 获得 ISA 下载链接。

EVTK 在 IBM Support Assistant 中可以免费下载。 如果您尚未安装 IBM Support Assistant,则需要先下载。 (有关链接,请参阅 参考资料)。 安装 IBM Support Assistant 之后,您可以安装 EVTK 插件。 可以在 IBM Support Assistant 的 Updater 页面上下载 EVTK,它位于 Common Component Tools 部分中的 New Plug-ins 选项卡下,如图 2 所示:

图 2. 安装 EVTK
安装 EVTK

您还需要通过安装产品插件让 IBM Support Assistant 知道您使用的产品包括 JVM,如图 3 所示。例如,您可能想从选择 Others 部分选择一个用于 Java 的开发人员套件或从 WebSphere 部分中选择一个 WebSphere 产品。

图 3. 安装产品插件
安装 IBM JDK 的产品插件

安装插件之后,需要重新启动 IBM Support Assistant。 可以在 Tools 页面上启动,如图 4 所示:

图 4. 启动 EVTK
启动 EVTK

常见任务

现在让我们使用 EVTK 执行一些基本的日志分析任务。

打开要进行分析的日志

若要使用 EVTK 分析详细的 GC 日志,请启动 EVTK,然后从 File 菜单中选择 Open File。EVTK 将在具有四个选项卡的编辑器中打开该日志,如图 5 所示。 您可以从运行的应用程序中打开日志,但是 EVTK 不会 自动更新显示。若要刷新显示,请单击 Reset Axes 按钮。

图 5. EVTK 编辑器中的选项卡
EVTK 编辑器中的选项卡

选项卡如下:

  • 用文件名进行标记的选项卡显示日志本身的文本。如果日志很大, 则 EVTK 将不会显示所有文本,而仍然要对整个日志进行解析。
  • Data 选项卡显示 EVTK 生成数据的原始视图。该数据适合 剪切并粘贴到电子表格中。
  • Line Plot 选项卡显示数据。
  • Report 选项卡显示 EVTK 对该数据的报告、每个所选字段的摘要、 整个日志的表格式摘要以及一系列调整建议。

VGC Data 菜单,如图 6 所示,显示可以查看的所有字段。灰显的字段是 EVTK 已经进行了查找但没有在当前日志中找到的字段。 如果未选择 Summary 字段,则可以选择该字段来启用表格式的摘要。 同样,还可以启用 Tuning Recommendation 以获得建议。

图 6. VGC Data 菜单
VGC Data 菜单

对比多个文件

EVTK 允许您同时分析多个文件。这对于 评估性能更改效果非常方便。 图 7 显示使用三个 GC 策略执行固定工作负载的应用程序。 (这种情况下,应用程序本身便是 EVTK。) 实线是 gencon GC 策略,点线是 optavgpause 策略, 虚线是 optthruput 策略。EVTK 基于日志文件名称得出行标签。 (有关不同类型的 GC 策略的详细信息,请参阅 参考资料 中的文章 “垃圾收集策略第 1 部分”)。

图 7. 三种不同的垃圾收集策略的堆使用情况和暂停时间
三种不同的垃圾收集策略的堆使用情况和暂停时间

这种情况下,根据所有评测条件,gencon 模式明显最佳。它完成任务的速度最快、过程中使用的堆最少并且 GC 暂停时间更短。 但 gencon 策略 不是默认的策略;在大多数情况下,optthruput 是默认策略,它胜过 gencon。 正如此例所示,尽管它并不总是胜过 gencon 策略,因此 当使用不同的 GC 策略时,应该查看应用程序如何改变行为。 通常,非常简单的更改(如更改应用程序使用的 GC 策略)会产生非常大的改进。

放大问题阶段

EVTK 允许您侧重于日志中特定的时间段。 当放大特定时间段时,所有摘要数据和建议都会更改以只反映该时间段。 例如,图 8 中所示的日志显示白天繁忙但夜晚空闲的应用程序的堆使用情况:

图 8. 白天繁忙但夜晚空闲的应用程序的堆使用情况
白天繁忙但夜晚空闲的应用程序的堆使用情况

对于整个日志来说,GC 开销 (即花费在执行 GC 上的时间)大约为 5%,这是非常不错的。但是,这包括应用程序未执行任何工作以及不需要 GC 时的较长时间段。放大特定时间段可以更精确地反映繁忙期间系统的行为, 如图 9 所示:

图 9. 放大繁忙阶段
放大繁忙阶段

EVTK 还允许您侧重于数据的特定范围。例如, 您可能只对非常长的暂停或堆大于 500MB 的阶段感兴趣。 您可以通过更改 Y 轴的值进行此类筛选。

更改单位

EVTK 允许您更改显示单位。 更改单位将更改绘图的方式,还会更改摘要表以及调整建议中的单位。

默认情况下,时间(X 轴上的单位)的显示单位为秒。这对于短时间运行非常方便, 但对于涉及较长时间段的日志不太理想。若要更改为不同的单位,请从右侧的下拉菜单中选择首选的单位,如图 10 所示。可能包括小时、分钟、日期和 GC 编号,该编号只是收集的序号。Normalize 复选框确定是使用相对于日志(规范)开始的时间还是使用绝对时间(非规范)。

图 10. 更改单位
更改单位

您还可以更改 Y 轴上的单位。例如,您可以将堆的数量(默认情况下以兆字节为单位进行显示)更改为千兆字节或更改为总堆的百分比。

使用和导出模板

您经常会发现自己查看的是相同的字段组合。 在 EVTK 中,模板 允许您保存这些组合以便以后使用。 Templates 视图位于窗口左上角,如图 11 所示:

图 11. Templates 视图
Templates 视图

双击模板可将其应用于当前数据集。 EVTK 附带一些预定义的模板。Heap 模板对于评估 应用程序的内存使用和需求非常有用。Pauses 模板是诊断怀疑可能与 GC 有关的性能问题的第一步。

您可以通过以下方法来导出模板,即调用 View 菜单或通过右键单击 Templates 视图的任意位置,然后选择 Export current settings as template。键入模板的名称, 然后,EVTK 将该模板保存在 Templates 视图中以便将来使用。

更改颜色

您可以选择 EVTK 用于绘图的颜色。单击 View 菜单中的 Preferences 项,然后导航到 Displayers 类别中的 Display colors 页面,如图 12 所示:

图 12. 颜色首选项页面
模板视图

保存输出

您可以保存所有 EVTK 输出,方法是右键单击主面板,然后从所得到的上下文菜单中选择 Save,如图 13 所示。线图可以另存为 JPEG 图像,报告可以另存为 HTML,原始数据可以另存为 CSV 文件。本文中的图形是 从线图视图保存的。

图 13. 保存
保存

使用建议

EVTK 提供详细 GC 日志中感兴趣的功能摘要及其调整建议。 摘要和建议可通过 Report 选项卡中的报告获得。

为什么需要进行干预并执行某些手动调整? 垃圾收集器为了优化其性能已经执行了很多自动调整。 但是,它不知道您的优先级,也不知道在没有任何指导的情况下 将对哪些方面进行取舍。 对于所有工作负载和所有环境来说没有最优配置。 您可以执行的最简单的调整就是指定一个策略并告诉垃圾收集器是吞吐量重要还是暂停时间最重要。 如果您敢于冒险或更渴望获得最佳性能,则可以尝试调整堆的大小、 改变 nursery 的大小或尝试更大的最大 nursery 大小。

案例研究:诊断内存泄露

查看详细 GC 日志的主要原因之一就是 检查应用程序的内存使用情况并确保其在 某些方面没有问题。 例如,应用程序可能使用高于期望的内存, 并且详细 GC 输出可以提供有关应用程序内存占用的指示。 内存泄露是相关但更严重的问题。 Java 平台的 GC 实用工具确保 Java 应用程序不会泄露内存,即使丢失了对对象的所有引用之前没有释放对象也是如此。但是,如果应用程序没有正确地持有对象引用,则仍然有可能会泄露,因为垃圾收集器 将不会收集仍然被引用的对象。

软引用和弱引用

软引用 是在堆中可用空间不足的情况下可以清除的引用。 它们对于内存敏感的高速缓存非常有用。弱引用 是 在所引用对象没有其他引用时将被清除的引用。 它们对于将元数据与对象关联的映射以及维护侦听器列表非常重要。 当然,如果想永久保留映射中的所有内容,它们不太理想。

通常,诊断内存泄露非常简单。在应用程序上 启用详细 GC,将它运行一段时间,然后在 EVTK 中绘制使用的堆(收集之后)。 当应用程序正在初始化或者应用程序的工作负载增加时,应用程序的内存使用自然也将增加。 如果没有任何明显的原因应用程序要增加内存要求时,使用的堆的线条向上蔓延, 则有可能存在泄露。EVTK 查找该模式并添加调整建议的注释(如果检测到可能存在泄露)。

虽然详细 GC 可能显示存在泄露,但它没有告诉您是哪个对象引起的这个泄露。在某些情况下,通过检测代码才能够发现。考虑哈希映射和其他集合。它们所有都是静态的吗?它们是否都有删除对象以及添加对象的机制?应用程序对其缓存对象是否过于慷慨?对象轮询也可能是内存泄露的原因。

如以下示例所示,弱引用和软引用都是解决内存泄露的强大工具。(有关它们的详细信息,请参阅 随附的侧栏,有关何时以及如何使用它们的论坛的链接,请参阅 参考资料。)考虑确定有泄露的应用程序,如清单 1 所示。 它添加到映射,但从不清除它。

清单 1. 内存严重泄露的 Java 类
public class Leaker
{
	private Map things = new HashMap();

	public void leak() {
		while (true) {
			things.put(new Date(), new Leak());
		}
	}

	private class Leak
	{
		private Object data;

		public Leak() {
			data = new Object();
		}
	}
}

图 14 显示该应用程序的堆使用情况。 堆使用中的骤降标记了对堆进行压缩的点。当 JVM 内存不足时,日志结束。

图 14. 泄露严重的应用程序的堆使用情况
泄露严重的应用程序的堆使用情况

使用弱引用来避免泄露

切换到 WeakHashMap,如清单 2 所示,立即更正该问题;新的改进的堆使用情况如图 15 所示。堆使用从不会超过 1MB,并且应用程序可以继续保持不确定地运行。

清单 2. 对防止内存泄露的 Leaker 类的简单更正
	private Map things = new WeakHashMap();
图 15. 使用 WeakHashMap 修复可能存在泄露的应用程序
已修复泄露的应用程序的堆使用情况

但是,弱引用可能不足以更正某些泄露。如果图 15 中的映射是链接的列表,如清单 3 所示,那会发生什么情况呢?

清单 3. 对再次引用泄露的 Leaker 类的进一步修改
public class Leaker
{
	private Map things = new WeakHashMap();

	public void leak() {
		Object previousThing = null;
		while (true) {
			final Leak thing = new Leak(previousThing);
			things.put(new Date(), thing);
			previousThing = thing;
		}
	}

	private class Leak
	{
		private Object data;

		public Leak(Object thing) {
			/* Make a linked list */
			data = thing;
		}
	}
}

弱引用告诉垃圾收集器如果某个对象除了弱引用之外没有其他任何引用,则应该收集该对象。 由于映射中的每个对象都持有一个对以前的对象的引用, 因此将不会清除任何弱引用并且应用程序将快速消耗完内存,如图 16 所示:

图 16. 无法使用 WeakHashMap 修复的内存泄露应用程序中的堆使用
无法使用 WeakHashMap 修复的内存泄露应用程序中的堆使用

确保弱引用如期工作

通过在 EVTK 中绘制被清除的弱引用的图,可以证实该问题,如图 17 所示。 向列表中添加链接之后,被清除的弱引用的数量将从较大的数更改为完全没有。(修改后的应用程序 沿着 X 轴零点的线条非常短,而以前的应用程序 的线条则又长又高。)很明显,弱引用不再起作用。

图 17. 对可能存在内存泄露的应用程序的两个变体清除弱引用
对可能存在内存泄露的应用程序的两个变体清除弱引用

在这种情况下,解决办法就是也将链接列表中的链接更改 为弱引用。执行如清单 4 中所示的代码更改之后, 弱应用的数量大大增加了,而且堆使用也返回到最小值:

清单 4. 引进更多弱引用将防止对引用的持有超过必需的时间
private class Leak
{
	private WeakReference reference;

	public Leak(Object thing) {
		this.reference = new WeakReference(thing);
		/*
	        * We can get back our object from the reference with
	        * reference.get(), but we should always check it for null.
	        */
	}
}

通过使用 EVTK 查看被清除的弱引用的数量,您可以轻松验证对使用弱引用的重新设计是否切实有效。

如果代码检测没有快速找到泄露,则您可能需要执行 一些应用程序转储并分析它们以找到引用增加了的对象。 有关查找和更正内存泄露问题的文章,请参阅 参考资料

详细 GC 日志还可以帮助评估应用程序的可伸缩性。例如, 如果应用程序的目的是要处理大量数据,但当测试期间处理少量数据时, 该应用程序却使用非常多的内存, 则该应用程序未能按预期进行伸缩。

案例研究:调整堆的大小

很多开发人员都使用详细 GC 数据来帮助 选择堆的最佳大小。 如果堆太小以至于无法容纳应用程序所需的数据,则该应用程序将消耗完内存并且使用 OutOfMemoryError 终止。如果堆具有应用程序数据的空间,但没有大量空间备用,则垃圾收集器必须 花费很多时间确保堆中具有用于新分配的空间,这将会降低应用程序的性能。堆太大通常不会对应用程序有负作用,但这样非常浪费,并且 GC 暂停可能也比较长。通常,同一机器上会同时运行其他应用程序,因此重新分配内存,使每个 Java 应用程序都具有适量的内存是非常明智的。

垃圾收集器将尝试适当调整堆的大小,但将避免使用同一机器上多半的可用物理内存。还需要花费一段时间来增加堆的大小以便获得最优大小,如果应用程序占用下降,则可以缩小堆。堆大小的这些上下浮动可能会降低应用程序的速度,但如果同一系统上运行的其他程序不需要物理内存,则没有必要这样。如果正确理解了应用程序的内存要求,则固定堆大小便是一个简单的性能优化问题。

对于堆来说,没有一个理想的堆大小。通常,堆大小越大 应用程序执行得越好,因此调整堆大小涉及 权衡应用程序的要求以及物理内存的其他需求。 比较合理的试探是 堆大小应该至少为活动数据的数量的两倍。 如果这不可能实现或者想使堆更大,则 gencon 策略可能是最佳选择,因为在堆大小受限制的情况下,该策略一般胜过 optthruput 策略。 如果这些都有可能,则不应该调整堆大小以便机器需要使用 虚拟内存来容纳它。使用虚拟内存会大大降低性能。

固定堆大小的优势

图 18 显示了当 图 7 中的相同工作负载运行在堆大小固定为 500MB 的 JVM 中的暂停时间,命令行选项为 -Xms500m -Xmx500m。 仅仅根据暂停时间判断,固定堆大小似乎使问题变得更糟。 每个策略的平均暂停时间都增加了,但花费在 GC 上的时间比例并没有改变。 因此实际上总的暂停时间(报告视图中表的第四列) 大大下降了。 总的暂停时间和平均暂停时间似乎不一致,因为在小堆中收集完成得非常快。 当堆的大小可变时,尽管堆很小, 但 JVM 执行很多收集都非常迅速, 这些都导致平均暂停时间较短。在这种情况下, 最终的性能度量是 JVM 完成工作所花费的时间(线条的长度); 对于 gencon 策略,固定堆会提高 13%,对于 optavgpause 策略则会提高 15%,而对于 optthruput 策略则会提高 30%。

图 18. 在固定堆中运行的应用程序的暂停时间
在固定堆中运行的应用程序的暂停时间

当然,本示例针对的是 Java 程序,它执行时间超过 30 秒, 其中 JVM 将初始时间的大部分花费在查找最佳堆大小上面。 固定堆大小通常不会对长时间运行的程序有明显的改善。 如果没有正确理解工作负载,则固定堆大小是非常不明智的, 因为这样可能会迫使 JVM 在太小的堆中运行。 可以使用详细 GC 输出来 评估工作负载的稳定性以及 JVM 需要高于允许内存的风险。

案例研究:通过详细 GC 日志评估应用程序吞吐量

您可以调整 GC 以优化应用程序的性能。 但是如何确定应用程序执行得如何呢? 基准具有明确的性能度量,但是调整垃圾收集器 来优化基准,然后认为相同的配置将会为不同的应用程序提供最佳结果,这是非常不明智的。 所有应用程序都是不相同的,并且垃圾收集器没有最佳配置。 (如果有的话,垃圾收集器将提供该配置,那么调整就没有必要了。) 与基准不同的是,并非所有应用程序都提供显示其执行好坏程度的报告。

在这些情况下,详细 GC 日志本身就可以提供有关应用程序执行情况的最佳提示。 尽管详细 GC 日志是评估应用程序性能的好起点,而报告的暂停时间一定不是 正确的起点。 正如上文所示的固定堆示例,应用程序可能有时的运行速度比调整前快,但仍然由 未改变的 GC 开销甚至更长的平均暂停时间表示。花费大量时间执行 GC 的应用程序 的确看上去性能降低了,但由于对象的排列方式,在 GC 上花费更多时间有时可能会使应用程序执行得更好。

GC 如何加快应用程序的速度?

好的 GC 实际上会提高应用程序的性能。 如果对象布置紧密,则当它们使用 gencon 模式时或紧缩之后, 分配新对象将更迅速,因为 不需要搜索空闲列表。这在详细 GC 日志中度量不出来,但快速 分配大大有助于应用程序。如果对象布置适当, 以便在相同时间使用的对象不会彼此靠近(这称为区域性),则对象访问也将比以前更快。智能 垃圾收集器重新排列对象以便最大程度地提高访问对象的速度。

这里没有计算 GC 暂停时间对应用程序的影响, 而是查看生成的垃圾数量。 应用程序性能的一个最佳指标是 应用程序生成的垃圾的数量: 生成的垃圾越多,则应用程序必须执行的工作也就越多, 原因垃圾是应用程序工作的负作用。 由于收集了所有生成的垃圾, 因此生成垃圾的数量与垃圾收集器收集的垃圾数量完全相同。

您可以绘制收集的垃圾数量的图形,方法是 从 EVTK 的 VGC Data 菜单中选择 Amount freed。Report 选项卡上的图形 显示了有关在运行期间所收集的平均垃圾数量和总垃圾数量的统计信息。 平均释放数量并不能表示最佳性能;如果占用非常稳定,则每次收集释放的数量也可能非常稳定。 但是,如果应用程序执行得非常好,则当应用程序在更短的时间内执行更多的工作,收集的频率可能会随之增加。因此,在固定的时间段内,释放的总数量可以很好地表示性能。 如果在固定的时间段内没有收集日志,则放大该设置的时间段将确保只显示该时间段的总数量。

更好的性能指示器是 GC 的速率,因为即使您对不具备相同时间的日志进行比较,它仍然非常有意义。 该速率显示在 Report 选项卡顶部的表中。(如果未显示表,则尝试在 VGC Data 菜单中启用 Summary。) 让 GC 拥有较高的速率意味着应用程序在较短的时间内做完更多的工作 — 这是好事!

考虑前面固定堆的示例。平均暂停时间造成了有关 GC 执行性能的假象。 但是,如果您看一看 GC 的速率,便可以看出对于固定的堆来说这是较高的速率。例如,两个 optthruput 运行的比较,如图 19 所示, 其速率比提前设置堆大小时的速率高出 12%:

图 19. 垃圾收集速率的摘要视图
垃圾收集速率的摘要视图

您还可以将 GC 的速率看作是垃圾生成的速率。 乍看起来,垃圾生成似乎是一件坏事,并且应该尽量减少为好。 生成垃圾多的应用程序可能比生成垃圾少的应用程序性能更差,这是正确的。 因为应用程序花费太多精力在垃圾收集器上 — 但并不总是这样。例如,对象轮询会减少应用程序生成的垃圾数量,但严重降低了垃圾收集的性能。(有关其原因的讨论,请参阅 参考资料 中有关 urban 性能说明的文章。)通常,持有可以丢弃的对象引用 会减少生成的垃圾数量,但是这样会损害 GC。 如果您适当地限制了变量的范围并且减少实例变量的使用, 则可以减少此类对象保留。

如果应用程序负载不足 — 即它没有足够的工作可做 —, 则 GC 的速率不可作为良好的性能指示器, 因为如果没有工作可做,速率将会下降。例如, 如果所有客户机都断开连接,服务器将不会生成大量垃圾,但是这并不意味着需要调整服务器。 总之,当应用程序工作负载不足时,可能不需要进行大量调整。 如果目标是加快各个事务的速度,则在某段事务上放大 GC 日志将会提供合适的信息。

估计应用程序响应时间

关于本系列

IBM 的 Java 诊断 介绍了来自 IBM 的新工具,可帮助解决 Java 应用程序中的问题并提高性能。您可从每篇文章学到新的知识,并且马上就可以投入使用。

为本系列投稿的每位作者都属于一个新团队,它致力于 创建新工具帮助您解决 Java 应用程序的问题。每位作者都有着不同的知识背景,并为团队带来各种技能和专业领域的知识。

您可以单独联系各个作者,讨论您对这些文章的评论或问题。

与应用程序吞吐量相比,如果您更关心应用程序响应时间又会怎样呢?那么假设详细 GC 暂停时间 是应用程序响应时间的最佳指示器。但这只在某些时候是正确的,并且只有一半的正确性,因此您需要对暂停时间仔细推断。 如果应用程序工作负载不足, 则最大暂停时间将与最大响应时间有关。但是,通常平均 响应时间与吞吐量成正比。 因此,与具有短暂停时间的策略(如 optavgpause)相比,具有较长暂停时间的策略(如 optthruput) 实际上可能给出更低 的平均响应时间。 如果应用程序工作负载过重,则暂停时间甚至不太重要,因为工作可能必须排成队列进行服务, 因此响应时间可能很大程度上由队列的长度确定, 而队列的长度又由应用程序吞吐量确定。

结束语

如果仔细查看详细 GC 日志,通常会更好地了解应用程序的特性; 还将能够检测应用程序内存使用的潜在严重问题并且能够提高性能。 Extensible Verbose Toolkit 是一个功能强大的工具,可以从详细的 GC 中获得最多的可用信息。

参考资料

学习

获得产品和技术

讨论

条评论

developerWorks: 登录

标有星(*)号的字段是必填字段。


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件

 


在您首次登录 developerWorks 时,会为您创建一份个人概要。您的个人概要中的信息(您的姓名、国家/地区,以及公司名称)是公开显示的,而且会随着您发布的任何内容一起显示,除非您选择隐藏您的公司名称。您可以随时更新您的 IBM 帐户。

所有提交的信息确保安全。

选择您的昵称



当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

标有星(*)号的字段是必填字段。

(昵称长度在 3 至 31 个字符之间)

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

 


所有提交的信息确保安全。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=Java technology
ArticleID=266387
ArticleTitle=IBM 的 Java 诊断,第 2 部分: 使用 Extensible Verbose Toolkit 进行垃圾收集
publish-date=11022007