首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

一步步优化JVM5:优化延迟或者响应时间(1)

2012-08-03 
一步步优化JVM五:优化延迟或者响应时间(1)本节的目标是做一些优化以满足对应用对延迟的需求。这次需要几个

一步步优化JVM五:优化延迟或者响应时间(1)
    本节的目标是做一些优化以满足对应用对延迟的需求。这次需要几个步骤,包括完善Java堆大小的配置,评估垃圾回收占用的时间和频率,也许还要尝试切换到不同的垃圾回收器,以及由于使用了不同的垃圾回收器,需要重新优化Java堆空间大小。
    这一步有如下可能的结果:
    1、应用的延迟需求被满足了。如果这一步的优化操作满足了应用的延迟需求,你可以继续下一步优化(优化吞吐量)。
    2、应用的延迟需求未被满足。如果这一步的优化操作未能满足延迟需求,你可能需要重新看看延迟需求是否合理或者修改应用程序。一些可能的问题可以帮助改善应用的延迟问题:    a、优化Java堆以及修改应用以减少对象的分配和对象的长时间存活。    b、修改JVM的部署结构,让每一个JVM做更少的工作。
    上面的两个步骤都可以减少JVM的对象分配,因此减少垃圾回收的频率。
    这一步从查看垃圾回收对应用的延迟的影响开始,基于前面一节“决定内存消耗”计算出来的Java堆大小。
    下面列出了评估垃圾回收对延迟的影响需要进行的几个事情:    1、测量MinorGC的时间。    2、测量MinorGC的频率。    3、测量FullGC的时间。    4、测量FullGC的频率。
    测量垃圾回收的时间的和频率对于改善Java堆大小配置来说是非常重要的。MinorGC的时间和频率的测量结果可以用来改善young代的空间大小。测量最坏情况下FullGC的时间和频率可以用来决定old代的大小,以及是否需要切换成吞吐量垃圾回收器(通过使用-XX:+UseParalleOldGC或者-XX:+UseParallelGC)或者并发垃圾回收器(CMS,通过使用-XX:+UseConcMarkSweepGC)。在使用吞吐量垃圾回收器的时候,如果垃圾回收的延迟和频率太高以导致应用的延迟需求无法满足的时候才切换到CMS,如果选择了切换,需要对CMS垃圾回收器进行优化,后面会详细介绍这个问题。
    接下来详细介绍前面提到的各种情况。    需求    下面列举了几个这一步优化操作需求,它们来源于应用的系统需求:    1、可以接收的平均暂停时间。平均暂停时间需求用于和MinorGC消耗的时间比较。    2、可以接收的MinorGC的频率。其实频道对于应用负责人来说,没有平均延迟时间重要。    3、应用负责人能够接受的最大延迟时间。这个时间受到FullGC的影响。    4、应用负责人能够接收的最大延迟的频率,即FullGC的频率。其实,大多数时间应用管理员还是更加关心应用的的最大延迟时间超过了最大延迟的频率。
    一旦确定了需求,这些垃圾回收器的时间消耗和频率都可以通过垃圾回收日志收集到。先把垃圾回收器设置为吞吐量垃圾回收器(设置-XX:+UseParallelOldeGC或者-XX:+UseParallelGC)。通过反复测试,可以让young代和old代满足上面的要求。下面2节介绍如何优化young代和old代空间大小来观察MinorGC和最坏情况的FullGC的消耗时间和频率。       改善young代的大小    确定young代的大小是通过评估垃圾回收的统计信息以及观察MinorGC的消耗时间和频率,下面举例说明如何通过垃圾回收的统计信息来确定young代的大小。
    尽管MinorGC消耗的时间和young代里面的存活的对象数量有直接关系,但是一般情况下,更小young代空间,更短的MinorGC时间。如果不考虑MinorGC的时间消耗,减少young代的大小会导致MinorGC变得更加频繁,由于更小的空间,用玩空间会用更少的时间。同理,提高young代的大小会降低MinorGC的频率。
    当测试垃圾回收数据的时候,发现MinorGC的时间太长了,正确的做法就是减少young代的空间大小。如果MinorGC太频繁了就增加young代的空间大小。
一步步优化JVM5:优化延迟或者响应时间(1)   一步步优化JVM5:优化延迟或者响应时间(1)    上图是一个展示了MinorGC的例子,这个例子是运行在如下的HotSpot VM命令参数下的。

   一步步优化JVM5:优化延迟或者响应时间(1)
    如果没有FullGC,可以人为的去干预,前面说过,可以使用VisualVM来触发FullGC。另外,评估FullGC的频率需要知道对象的转移率,这个转移率说明对象从young代转移到old代。接下来的介绍如何评估转移率。
    接下有个几个MinorGC的例子,他们被用来评估FullGC的频率。
2010-12-05T14:40:36.815-0800 [GC[PSYoungGen: 2047094K->247765K(2097152K)]3696985K->1900882K(6291456K), 0.0543332 secs][Times: user=0.37 sys=0.01, real=0.05 secs]


    从上面的例子可以看出:    1、Java堆的大小是6291456K或6144M    2、young代的大小是2097152K或2048M    3、old代的大小是6144M-2048M = 4096M
    在这个例子中,活动对象的大小差不多是1370M。那么old代还有2726M剩余空间(4096M-1370M=2726M)。
    填充完成2736M空间需要多长时间是由young代向old代的转移率决定的。这个转移率的计算通过查看每次MinorGC后old代的占用空间的增长情况以及MinorGC发生的时间。old代的空间占用是MinorGC之后Java堆中对象大小减去young代的大小,通过这个公式计算,可以看出在这个例子中每次MinorGC之后,old代的空间占用情况是:
    1588635K,第一个MinorGC    1611428K,第二次MinorGC    1632106K,第三次MinorGC    1653117K,第四次MinorGC
    每次的增量分别是    22793K,第一次和第二次的增量    20678K,第二次和第三次的增量    21011K,第三次和第四次的增量
    平均每次MinorGC转移大概201494K或者叫21M。
    如果剩余的空间都是按照设个转移率来转移到old代的话,且知道MinorGC的频率是每2.147秒一次。因此,这个转移率是201494K/2.147s差不多10M/s,那么一共的空间是2736M空间需要273.6s差不多4.5分钟一次。
    因此,通过前面的案例分析,应用的最差延迟的频率是4.5分钟。这个评估可以通过让应用处于稳定运行状态超过4.5分钟来验证。
    如果评估和观察的FullGC的频率高于了应用对最坏延迟频率的要求,那么可以提高old代的空间大小。如果改变old代的大小,保持young代的空间恒定,在优化young代的时候也说这个问题,两者应该独立优化,以保证有高效。
    如果这步已经达到了你最坏延迟的要求,那么这一步调优延迟就算已经完成了,就可以进入下一步去调优“吞吐量”了。       如果你未能达到了应用对最坏延迟时间和频率的性能要求,由于FullGC的执行时间太长了,然后你可以把垃圾回收器切换CMS(concurrent garbage collection)。CMS有能力让垃圾回收尽量是多线程的,即让程序保持在运行状态。要使用CMS可以通过下面这条命令选项:-XX:+UseConcMarkSweepGC。        后面详细说明如何调优CMS。

热点排行