我们正在执行项目中的性能测试和调优活动。我使用了article
中提到的JVM配置精确的JVM选项是:
set "JAVA_OPTS=-Xms1024m -Xmx1024m
-XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=1024m
-XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled
-XX:+UseCMSInitiatingOccupancyOnly
-XX:CMSInitiatingOccupancyFraction=50
-XX:+PrintGCDetails -verbose:gc -XX:+PrintGCDateStamps
-XX:+PrintGCApplicationStoppedTime
-XX:+PrintGCApplicationConcurrentTime
-XX:+PrintHeapAtGC -Xloggc:C:\logs\garbage_collection.logs
-XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10
-XX:GCLogFileSize=100m -XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=C:\logs\heap_dumps\'date'.hprof
-XX:+UnlockDiagnosticVMOptions"
我们仍然看到问题没有解决。我确信在我们的代码(线程实现等)和我们使用的外部库(如log4j等)中存在一些问题,但我至少希望通过使用这些JVM调优选项来提高性能。
来自Gceasy.io的报告表明:
由于缺少计算,您的应用程序似乎正在等待 资源 (CPU或I / O周期)。严肃的生产应用不应该 因计算资源而陷入困境。在1个GC事件中,'真实'时间花了 超过' usr' +' sys'时间。
一些已知的代码问题:
- 对于只接受一个的外部webapp,有很多网络流量 一次连接。 但是这种延迟对我们的申请来说是可以接受的。
- 某些线程在Log4j上阻塞。我们使用Log4j进行控制台,数据库和文件追加。
- MySQL调优也可能存在问题。但就目前而言,我们希望排除这些可能性,并了解可能影响我们执行的任何其他因素。
醇>
我希望通过调优,应该减少GC活动,应该正确管理元空间。但这没有观察到为什么?
以下是一些快照:
答案 0 :(得分:2)
您似乎没有GC问题。以下是您运行应用程序超过40小时的GC暂停时间图:
从这张图中我们可以看到大多数GC暂停时间都低于0.1秒,其中一些在0.2-0.4秒内,但由于图表本身包含228000个数据点,因此难以计算了解数据的分布方式。我们需要一个包含GC暂停时间分布的直方图。由于绝大多数这些GC暂停时间非常短,只有很少的异常值,因此在线性直方图中绘制分布并不能提供信息。所以我创建了一个包含那些GC暂停时间的对数分布的图:
在上图中,X轴是GC暂停时间的10个基准对数,Y轴是出现的次数。直方图有500个箱子。
从这两个图中可以看出,GC暂停时间被分为两组,大多数GC暂停时间都非常低,大小为毫秒或更短。如果我们也在y轴上的对数刻度上绘制相同的直方图,我们得到这个图: 在上图中,X轴是GC暂停时间的10个基数对数,Y轴是出现次数的10个对数。直方图有50个区间。
在这张图上,它变得可见,我们你有几十个GC暂停时间,可能是人类可以测量的,它们的数量级为十分之几秒。这些可能是您在第一个日志文件中拥有的120个完整GC。如果您使用具有更多内存和禁用交换文件的计算机,则可以进一步减少这些时间,以便所有JVM堆保留在RAM中。交换,特别是在非SSD驱动器上,可能是垃圾收集器的真正杀手。
我为您发布的第二个日志文件创建了相同的图表,这是一个小得多的文件,大约8分钟的时间,包含大约11000个数据点,我得到了这些图像: 在上图中,X轴是GC暂停时间的10个基准对数,Y轴是出现的次数。直方图有500个箱子。 在上图中,X轴是GC暂停时间的10个基数对数,Y轴是出现次数的10个对数。直方图有50个区间。
在这种情况下,由于您已在其他计算机上运行应用程序并使用不同的GC设置,因此GC暂停时间的分配与第一个日志文件不同。它们中的大多数都在亚毫秒范围内,在百分之一秒的范围内有几十,几百。我们这里也有一些异常值在1-2秒范围内。有8个这样的GC暂停,它们都对应于发生的8个完整的GC。
两个日志之间的差异以及第一个日志文件中缺少高GC暂停时间可能是因为运行生成第一个日志文件的应用程序的机器比第二个日志文件的RAM高两倍(8GB vs 4GB)和JVM也配置为运行并行收集器。如果您的目标是低延迟,那么您可能最好使用第一个JVM配置,因为似乎完整GC时间始终低于第二个配置。
很难说出您的应用存在什么问题,但似乎与GC不相关。
答案 1 :(得分:1)
我要检查的第一件事是磁盘IO ......如果你的处理器在性能测试期间没有100%加载,很可能是磁盘IO有问题(例如你正在使用硬盘驱动器)......只需切换SSD(或者-memory disk)来解决这个问题
GC只是做它的工作......你重新选择了concurrent collector
来执行GC。
大多数并发收集器同时执行大部分工作(例如,在应用程序仍在运行时)以防止垃圾收集暂停。它专为具有中型到大型数据集的应用而设计,其中响应时间比总吞吐量更重要,因为用于最小化暂停的技术会降低应用程序性能。
您看到的内容与此说明相符:GC需要时间,但主要是"不要长时间暂停申请
作为选项,您可以尝试启用Garbage-First Garbage Collector
(使用-XX:+UseG1GC
)并比较结果。来自文档:
G1计划作为Concurrent Mark-Sweep Collector(CMS)的长期替代品。将G1与CMS进行比较揭示了使G1成为更好解决方案的差异。一个区别是G1是压缩收集器。此外,G1提供比CMS收集器更可预测的垃圾收集暂停,并允许用户指定所需的暂停目标。
此收集器允许设置最大GC相位长度,例如添加-XX:MaxGCPauseMillis=200
选项,表示您在GC阶段耗时少于200毫秒之前就行了。
答案 2 :(得分:1)