您的位置:首页 > 其它

JRockit JVM优化清单/调优指南

2014-08-29 09:53 148 查看

JRockitJVM优化清单/调优指南

作者:StevenPozarycki

时间:2007年12月13日

摘要

本文的目的是以清单的方式提供BEAJRockitJVM的调优信息。从深奥的命令行选项到迭代性能测试,本文涵盖了许多方面。大部分数据都是我与用户合作过程中收集的。您要是也有什么技巧的话,请告诉我,在本文的下一版中,我会尝试将它们添加进去。
具体的产品版本信息都已在适当的地方列出;但是,本文所提供的通用指南适用于JRockit的大多数版本。每个版本的JRockit都增加了新的设置和优化,所以请查看发行说明和JRockit产品中心。

验证当前的JRockit环境

首先需要确定您的运行时应用程序服务器所使用的JRockit的版本。为此,可以查看相应应用程序服务器的日志文件。也可以使用适当的脚本设置系统环境,然后执行
java–version
命令来确定
JRockit的版本。
接着,收集当前JVM标志,开发和/或生产阶段需要用到它们:
-server-Xms1024m-Xmx1536m-Xverboselog:gc.log-Xverbose:memory

-Xgcprio:throughput

这将告诉您当前JRockit实例的配置情况。

确定应用程序的目标

确定应用程序的目标是什么。是“响应快”还是“性能高”?根据目标的不同,需要设置不同的垃圾收集算法。
例如,如果应用程序的目标是实现高性能,则确保设置了DynamicGarbageCollector
"-Xgcprio:throughput"
选项。如果目标是响应时间短,那么需要将
-Xgcprio:pausetime
-Xpausetarget=XXX'
中的
pausetarget
设置为最佳值。有关更多细节,请查看
JRockit调优文档。

收集故障诊断数据

如果JVM性能有问题,那么最好是先收集一些分析数据。该工作可以由团队中有相关经验的人员来完成,您也可以将这些信息发送给BEASupport做进一步分析。
首先,出现问题时需要收集大约10分钟的运行时JRockitRecording(JRA)数据。可以使用jrcmd.sh实用工具或JRockitMissionControl(JRMC)完成此操作。请阅读“性能测试期间的JRCMD/JRA”和“JRockit
MissionControl”两节的内容。
有关详细信息,请参阅
JRockitMissionControl文档。LatencyAnalysis一节提供许多有价值的内容,我们可以从中了解任何潜在的延迟问题(在JRockit中需要一个许可证就可以使用它)。
然后,需要收集问题发生时的一些详细日志。方法是在启动服务器实例的时候在JVM命令行输入以下参数:
-Xverboselog:perTestGC.log

-Xverbose:opt,memory,gcpause,memdbg,compaction,gc,license

-Xverbosetimestamp-Xgcreport

这样会将有价值的分析数据收集到刚才配置的
perTestGC.log
文件中。团队成员和
/
BEASupport可以对这些数据进行分析。
最后一点:通常,应用程序不会请求执行垃圾收集(也就是在应用程序代码中调用
System.gc()
)。但如果您怀疑它有问题,那么可以在启动服务器实例的时候,在Java命令行使用
-XXnoSystemGC
参数来禁用它。

现在,我将介绍如何通过迭代性能测试方法解决这些问题。

迭代性能测试方案及其方法

完成初始数据的收集和分析后,我们可以通过迭代方法来调优JVM。此处介绍的测试方案是在JRockitJVM层执行迭代调优的通用方法,可以找到哪些设置可能有益于特定应用程序。假定您有测量性能结果的方法;然后,可以将它们与“基准”(您应该已经有了)进行比较。

测试1:线程本地区域大小和大对象大小

在本测试中,我们将查看线程本地区域大小。这很重要,因为如果这些标志的默认设置对于应用程序不是最佳的(多数情况下是这样),那么就会造成堆锁定,这将对性能产生影响。将大部分对象限制在一定范围内对整体性能有益。

分析收集的JRARecording数据

分析结果,查看
-XXtlasize
-XXlargeobjectlimit
是否需要调优(请记住,对于多数应用程序,根据
eDocs,线程本地区域大小应该至少是大对象大小的两倍
)。这些内容位于
JRARecording首页的右上方。请查看下面关于tlaSize和largeObjectLimit的信息。在JRockit
R27.3之前的多数情况下,这些都不必调优。

注意:为了确保在稳定状态下获取配置文件和度量,应用程序需要有足够的热启动时间。要在性能分析过程中检查是否符要求,可以查看JRARecording中的优化标签,其中性能分析前后的优化数量和优化时间应该大致(理论上应该是准确地)相等。

测试2:锁性能分析

现在让我们看一下锁性能分析,它会显示在应用程序中是否有过多的锁定。如果确实如此的话,那么将对整体性能造成影响。

运行测试(启用
-Djrockit.lockprofiling
),分析这些结果。确定没有通过JVM启用的日志。该标志大概会占用5%到10%的系统开销,一个单独的测试将收集该数据,此时性能被忽略,唯一做完的分析是锁定分析。

-server-Xms1536m-Xmx1536m-Djrockit.lockprofiling


在相同测试中,使用jrcmd.sh实用工具或JRockitMissionControl(JRMC)热启动应用程序后,运行10分钟的JRARecording。有关如何使用该工具的信息,请参见电子文档。
使用top和iostat选项监控操作系统,如果需要的话还可使用ctrhandler.act文件指定的信息执行线程转储。
分析结果。

测试
3
:调优
tlaSize
largeObjectLimit

在这个测试中,我们将根据前面测试的结果调优线程本地区域大小和大对象限制。

确定JVM未启用日志。将
–XxtlaSize
-XXlargeObjectLimit
的值设置较高一点可能会有所帮助。但是,要验证和比较这点则需要需要长时间运行测试。对于
R27.2,将
preferredSize
设置为
16k
可能有所帮助。您可以查看关于这一问题的
详细信息。为此要,更改TLA设置并使用与测试1相同的Java命令行选项重新运行测试;增加
-XXtlaSize
-XXlargeobjectlimit
TLA值设置。相关信息,请参见
tlaSize
注意:在R27.3之前,提高性能通常不需要调优这些标志。事实上,过度调优这些标志很可能带来负面影响。
在相同测试中,使用jrcmd.sh实用工具或JRockitMissionControl(JRMC)热启动应用程序后,运行10分钟的JRARecording。关于如何使用该工具的信息,请参见电子文档。

使用top和iostat选项监控操作系统,如果需要的话还可使用ctrhandler.act文件指定的信息执行线程转储。

分析结果。

测试4:调优垃圾收集算法

本节测试的目的是运行各种不同的垃圾收集算法设置,并查看哪种设置对于应用程序最佳。关于-XXsetGC标志的详细令牌,请阅读以下内容。JRockit将以调优的nursery大小运行并移除
-Xgcprio:throughput
标志。该
throughput选项将在这些双版本的垃圾收集器之间自动切换,但进行直接的选择可能带来一些额外的性能上的好处。Nursery调优的目的是使被提升的对象保持较少的数量,因为这是nursery收集中代价高的部分。通过增加和减小nursery的大小对其调优。nursery的大小主要依赖于对象生存的时间,因为如果它们生存着,则在YC期间会得到提升。运行
jrcmd
<PID>
版本查看哪个当前垃圾收集器策略是活动的。


a.测试4-1:

1.使用
–XxsetGC
垃圾收集算法设置运行测试。该测试将设置垃圾收集选项为单倍行距加上并行
标记算法和并行扫描算法
;还要手动调优
nursery大小:
-server-Xms1536m-Xmx1536m-Xns:384m-Xverboselog:perTestGC.log

-Xverbose:opt,memory,gcpause,memdbg,compaction,gc,license

-Xverbosetimestamp-Xgcreport-XXnoSystemGC-XXsetGC:singleparpar

2.在相同测试中,使用jrcmd.sh实用工具或JRockitMissionControl(JRMC)热启动应用程序后,运行10分钟的JRARecording。关于如何使用该工具的信息,请参见电子文档。
3.使用top和iostat选项监控操作系统,如果需要的话还可使用ctrhandler.act文件指定的信息执行线程转储。
4.分析结果。

b.测试4-2:

1.用
–XxsetGC
运行一个使用垃圾收集算法集的测试。该测试将设置垃圾收集选项为分代的(双倍行距)加上并行
标记算法和并行扫描算法
;还要手动调优
nursery大小:
-server-Xms1536m-Xmx1536m-Xns:384m-Xverboselog:perTestGC.log

-Xverbose:opt,memory,gcpause,memdbg,compaction,gc,license

-Xverbosetimestamp-Xgcreport-XXnoSystemGC-XXsetGC:genparpar

2.在做这个测试的时候,使用jrcmd.sh实用工具或JRockitMissionControl(JRMC)收集应用程序热启动并运行后10分钟的JRARecording。关于如何使用该工具,请参见eDocs。
3.使用top、iostat,需要的话,还可用带有ctrhandler.act文件给定的信息的线程转储来监控正在运行的系统。
4.分析结果。

c.测试4-3:根据前面的
-XXsetGC:genparpar
测试向上或向下调优
nursery大小。
d.测试4-4:用
-Xgc:gencon-Xns50m
(和设为收集规格的日志)试试。

e.测试4-5:用
-Xgc:parallel-XXcompactratio:1
(和设为收集规格的日志)试试。


测试5:调优垃圾收集线程

本测试的目的是查看
gcthreads
标志设置对整体性能的影响。


根据前面的结果,调优
-XXgcthreads
标志为
实际
物理
CPU的数量并重新运行测试(由于这些值默认是基于机器上核心和硬件线程的数量,所以这应该是自动调优的)。您可以查看在“收集故障诊断数据”一节收集的详细输出日志来对其验证。更多细节请参见gcThreads
flag。

测试6:调优锁争用

如果在胖锁(fatlock)上存在锁争用,则可以用
-XXdisableFatSpin
禁止它们,或者用
-Djrockit.useAdaptiveFatSpin=true
JRockit自适应地禁止它们。当测试2启用
-Djrockit.lockprofiling
时,
可以通过
JRA中查看那个标签来确定这一点。更多细节,请参见locking
inJRockit。

测试7:调优Xeon硬件

如果运行在Xeon硬件之上,那么可以添加
-XXallocPrefetch
-XXallocRedoPrefetch
,它们与
TLA和LargeObjectLimit一起将有助于减少内存分配的开销。有关详细信息,请参见allocPrefetch标志。为了得到最佳的结果,您可能会在BIOS中禁用硬件预取指令。虽然操作方式取决于BIOS的牌子,但参数的名称通常都为“Hardware
Prefetcher”、“AdjacentSectorPrefetcher”、“AdjacentCacheLinePrefetcher”等。更多信息请参见Intelonthissubject。

测试8:将堆放入largePage

这会将堆锁入内存,使操作系统不能将其交换出来。更多信息请参见largePages标志,有关Linux操作系统端配置的更多信息还可以参考在Linux上配置-XXlargePages一节。在JRockit
R27版中,该选项的名称为
-XlargePages
。根据前面的结果,调优
-XlargePages
标志可能有所帮助,但可能也没有。使用该标志运行测试,查看结果否对整体性能有帮助。

测试9:用
-XXaggressive
标志测试

本节中的这些配置将使JVM高速运行并尽快达到稳定状态。为了实现此目标,JVM在启动时需要更多内部资源;但当目标一旦达成,它所需要的自适应优化将更少。我们推荐您为了那些单独工作的、运行时间长的、内存敏感的应用程序使用这个选项。更多细节请参见aggressive标志。
使用
-XXaggressive
标志运行测试,查看结果否对整体性能有帮助。

测试10:用
-XX:+UseNewHashFunction
标志测试

这个选项支持一个新的、更快的HashMap散列函数,它在Java5.0Update8中引入,从R27.1.0开始也是BEAJRockit的一部分。这个散列函数能够通过改进的散列扩展提高性能而不改变HashMap中元素存放的顺序。更多细节请参见UseNewHashFunction标志。
使用这个新的
-XX:+UseNewHashFunction
运行测试,,查看结果否对整体性能有帮助。

测试11:将暗物质减到最少

“暗物质”指被浪费的堆内存,它使堆成为许多碎片。了解如何最大程序地减少暗物质,以便当堆需要压缩时,整体吞吐量不受影响。请看以下选项:

使用分代的垃圾收集器(
-Xgc:gencon
or
-Xgc:genpar
)。在初始收集(nursery垃圾收集)期间,在nursery中被发现生存的对象被迁移到旧的一代。这样有好的副作用,当迁移对象时可以压缩它们。
提高压缩比(
-XXcompactionRatio=nn
)。通过将对象迁移到压缩块中、消除它们之间的暗物质,压缩减少了暗物质。
通过
-XXminBlockSize:<memSize>
选项修改规范(将什么视为暗物质?)。堆上小于最小块大小的块视为暗物质。因此,通过减小最小块大小,您最终减少了暗物质。但请注意,因为
JRockit为了释放堆空间必须做更细密的搜索,所以垃圾收集的时间会更长。最小块大小默认为2KB。

进一步测试:调优应用程序服务器层

最后,查看上述调优建议,调优WebLogicServer实例层。

结束语

本文提供的信息绝非一个完整的清单。但它会让您开始更好地理解和调优JRockitJVM层!

参考资料

JRockit调优文档
JRocikit参考文档:XFlags
JRocikit参考文档:XXFlags
HenrikStahl的Blog(JRockit的产品经理)
MarcusHirt的dev2dev页面(JRockitTool团队的负责人)

附录

以下内容为正文引用过的额外信息。

性能测试期间的JRCMD/JRA

使用命令行或者基于JRockitMissionControl(JRMC)Eclipse的工具都能够执行JRARecoding。我们可以使用JRMC连接到多个JRockitJVM,收集JRArecording,查看JVM的实时数据,检测和排除内存泄漏,以及查看应用程序内的潜伏物(执行缓慢“点”)。有关如何运行JRockitMissionControl,请参见下一节。
1.下载文档许可证。
2.
将下载的
license.bea
文件添加到
<JROCKIT_HOME>/jre
目录中。这样,完整路径将如下所示:
<JROCKIT_HOME>/jre/license.bea

3.运行JRCMD如下:
jrcmd.sh<PID>jrarecordingfilename=myrecording.xmltime=600
(该文件被写入本地目录或者指定的完整路径/文件名)或
jrcmd.sh<PID>print_threads

4.使用脱机JRA工具分析最后得到的
myrecording.xml.zip
文件。通过在
<JROCKIT_HOME>/bin
中执行
JRAbinary,将该JRA工具放入此目录下。
5.请查看JRCMD文档。

JRockitMissionControl

1.
使用
JRockit将下列内容添加到WebLogicInstance的启动行中:
java-Xmanagement:autodiscovery=true,ssl=false,authenticate=false,port=7091

2.
使用
<jrockit-install-directory>/bin/jrmc.exe(sh)
启动
JRockitMissionControl
3.如有必要,将JRMissionControl的license.beafile文件添加到:<JROCKIT_HOME>/jre/license.bea
4.在MissionControl的帮助下,JRARecordings、内存泄漏、潜伏物探查和监控能够全部在一处完成。

堆/线程的测试期快照

1.创建一个简单的、名称ctrhandler.act的文件并将其存放在
<JROCKIT_HOME>/jre/bin/jrockit
目录。

2.执行线程转储命令时,例如,kill-3),JRockit会查看此文件并执行命令列表。
3.ctrlhandler.act文件应该包含以下内容:
#ctrlhander.actfilelocatedinthe<JROCKIT_HOME>/jre/bin/jrockitdirectory

set_filenamefilename=./jrocket_control_breakoutput.txtappend=true

timestamp

print_threads

timestamp

version

print_class_summary

print_object_summaryincreaseonly=true

print_threads

print_threadsnativestack=true

print_utf8pool

timestamp

print_memusage

timestamp

heap_diagnostics

timestamp

#ThefollowingisoptionalandisanotherwaytogenerateaJRA

recording

jrarecordingfilename=./myjra.xmltime=600

在Linux上配置
-XXlargePages

问题:为何使用largePages?
回答:使用largePages的优点是可以锁定堆内存,并且不适用页面交换(还可以减少IOWait和GC)。在实际内存中,访问堆中的对象明显变快了。因此,为了实现性能目标,largePages选项是一个理想的选择。
1.如果机器支持大页面,则cat/proc/meminfo的输出将如下所示:
HugePages_Total:xxx

HugePages_Free:yyy

Hugepagesize:zzzKB

如果xxx为0,则没有分配任何大页面。
2.如果不为0,则需要使用CONFIG_HUGETLBFS(位于“Filesystems”下面)和CONFIG_HUGETLB_PAGE(当CONFIG_HUGETLBFS被选时,自动被选上)配置选项构建Linuxkernel。
3.接着,在Linux上分配大页。注意:只允许根用户分配大页面。
a.装载文件系统。JRockit使用hugepages文件系统,它驻留在内存中。这些步骤可以完成文件系统的安装。每次机器重启时都需要完成实际装载和chmod命令,或者也可以将其添加到一个/etc/rc.d/rc.local类型的文件:
mkdir-p/mnt/hugepages

mount-thugetlbfsnodev/mnt/hugepages

chmod777/mnt/hugepages


b.分配大页面。这是通过指定应该分配的内存数量来自动执行的。在分配过程中,这些面页将被保留起来,不能像普通页面那样使用。它们的分配和解除分配方式如下:
echo20>/proc/sys/vm/nr_hugepages

此处,数字20指应该保留的页面数量。要解除分配,可以将分配页面设置为0。(注意:请参见后面Q&A部分以确定正确的数量。)
如果并非所有请求的页面都被保留,那么可用内存就不够了。如果确要如此,内存很可能会有太多的碎片,那么我们的建议是重启机器。请注意,大页面不能被交换,所以一切都必须放在物理内存中。
RHEL3上,该文件的名称为
/proc/sys/vm/hugetlb_pool
,所以可以使用以下命令执行:

echo500>/proc/sys/vm/hugetlb_pool

这里的数字500指请求的大小为多少MB,而不是页数。如果JRockit不能够直接消除临时的大页文件,请别忘记在执行之后进行消除。否则,那些页在被释放之前将不可用。这对RedHatkernelbuild2.4.18-e.25.smp适用,而2.4.18-e.12.smp却不行。
问题:如何确定发给/proc/sys/vm/nr_hugepages的正确数量呢?
回答:因为要将整个Java堆放入largePages,所以必须根据堆的大小和页面大小来确定。为
/proc/sys/vm/nr_hugepages
确定正确的数量就像下面的例子那样简单,信息如下:

JVMMaxHeap=1536MB(1572864KBapprox)

HPAGE_SIZE=2MB

thenthevaluesentto/proc/sys/vm/nr_hugepageswouldbeapproximately7.7.(1572864MB/2MB)
注意:
尽管动态设置大页面的数量在理论上是可行的,但实践中并非如此。减少大页面的数量决不会有问题,但是增加大页面的数量就会产生问题。原因是,为了创建一个大页,Linux需要在内存中找到足够大的连续的区域。如果找不到,就不能创建大页面。
刚启动系统时,内存的碎片还不是很多,所以要找到足够大的连续的区域并不是问题。但机器运行时间一长,内存会产生更多的碎片。所以,如果要确保能够分配足够大的页面,就必须在启动刚完成时通过启动脚本或手动设置它们。
StevenPozarycki是BEASystems的首席系统工程师,主要负责架构解决方案和故障诊断,以及帮助用户解决任务关键型应用程序在BEA产品中出现的各类复杂问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: