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

一步步优化JVM6:优化吞吐量

2012-08-22 
一步步优化JVM六:优化吞吐量如果你已经进行完了前面的步骤了,那么你应该知道这是最后一步了。在这一步里面,

一步步优化JVM六:优化吞吐量
   如果你已经进行完了前面的步骤了,那么你应该知道这是最后一步了。在这一步里面,你需要测试应用的吞吐量和为了更高的吞吐量而优化JVM。
   这一步的输入就是应用的吞吐量性能要求。应用的吞吐量是在应用层面衡量而不是在JVM层面衡量,因此,应用必须要报告出一些吞吐量指标或者应用的某些操作的吞吐量性能指标。观察到的吞吐量指标然后用可以用来和应用需要的性能指标进行比较,如果达到或者超过要求,那么这一步就完成了。如果你需要更好的吞吐量的话,有一些JVM优化可以去做。
   这一步的另外一个输入就是,有多少内存可以供应用使用,就想前面说的GC最大化内存原则,越多可用的内存,性能就更好。这条原则不仅仅适用于吞吐量优化,同样适用于延迟优化。
   应用的吞吐量需求可能是无法满足的。如果是这种情况,那么就需要重新审视应用吞吐量的需求,应用就需要修改或者改变部署模型。如果上面的一种或者多种情况发生了,那么你需要重新进行前面的优化步骤。
   在前面的步骤里面,你可能使用吞吐量垃圾回收器解决了问题(通过-XX:+UseParallelOldGC或者-XX:+UsePrallelGC),或者你调整到并发垃圾回收器(CMS)来解决的问题。如果使用的CMS来解决的问题,下面有一些选项来提升应用的吞吐量,下面详细介绍。如果是使用的吞吐量垃圾回收器,我们将在CMS之后介绍。      CMS吞吐量优化
   能够用来提升CMS吞吐量的选项数量有限,下面列出一些可以单独使用或者联合使用的选项:
   1、使用一些额外的命令选项,在后面的“额外的性能命令行选项”中详细介绍。   2、增加young代的空间大小,增加young代的空间大小,可以减少MinorGC的频率,就能够减少在一段时间里面MinorGC占用的时间。   3、增加old代的空间大小,增加old代的空间,可以减少CMS垃圾回收的频率,减少潜在的碎片,可以减少stop-the-world垃圾回收。   4、进一步优化young代堆大小,已经在前面的“优化延迟和响应时间”里面说过了,以及如何优化eden空间任务后和survivor空间大小以减少对象从young代移动到old也在前面已经说过了。需要注意的是,当优化eden和survivor空间大小的时候考虑到一些权衡。   5、优化CMS周期的启动,也在前面说过了。      任何上面提到的优化,或者组合使用上面的选择,都是减少垃圾回收器占用CPU时间,把CPU留给应用计算。前面两种选择,提供一种可能性来提升吞吐量,但是会有stop-the-world垃圾回收的风险,会增加延迟。
   作为指导,不考虑CMS,MinorGC的次数应该减少10%,你可能只能降低1%-3%。通常来讲,如果只能减少3%甚至更少,那么能够提升的吞吐量空间恐怕就有限了。
   吞吐量垃圾回收器优化
   优化吞吐量垃圾回收器的目标是避免FullGC或者理想情况下,避免在稳定状态下FullGC。这个需要优化对象的岁数,这个可以通过制定survivor空间优化完成。你可以让eden空间更大,可以减少MinorGC的次数。我知道当对象的任期或者岁数达到一定值的时候就会移动到old代,而这个任期就是对象经历MinorGC的次数,MinorGC的次数越少,对象任期增长越慢,就有可能被MinorGC回收掉,而不是进入old代。
   使用HotSpot VM的吞吐量垃圾回收器,可以通过-XX:+UseParallelOldGC和-XX:+UsePrallelGC,这样可以提供最好的吞吐量。吞吐量垃圾回收器利用了一种叫做自适应大小的特性,自适应大小是基于对象的分配和存活率来自动改变eden空间和survivor空间大小,目的是优化对象的岁数分布。自适应大小的企图是提供易用性,容易优化JVM,以致于提供可靠的吞吐量。自适应大小在大多数应用下,能够很好的工作,但是关闭自适应大小以及优化eden空间和survivor空间以及old代空间是一个探索提升应用吞吐量的一种办法。关闭自适应大小会改变应用的程序的灵活性,尤其是在修改应用程序,以及随着时间的推移应用的数据发生了变化。
   关闭自适应大小可以使用选项:

 -Xmx14g -Xms14g -Xmn5g -XX:SurvivorRatio=3-XX:+UseParallelOldGC -XX:-UseAdaptiveSizePolicy-XX:PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintAdaptiveSizePolicy


   old空间还是9g,young代的空间是5g,比之前大了1g,eden还是3g,每一个survivor空间是1g。
   你可能需要重复多次设定大小,直到满足内存占用的条件下到达吞吐量的峰值。吞吐的峰值一般都是在对象最有效的老化的时候的达到的。
   通常的建议是,吞吐量垃圾回收器的垃圾回收的开销应该小于5%。如果你只能把这个开销降低1%甚至更少,你可能需要使用除本章描述之外的特别努力和很大的开销来优化JVM。  优化Parallel GC线程
   吞吐量垃圾回收器的线程数的优化同样基于有多少应用运行在同一个系统里面以及硬件平台。就像前面的“优化CMS”里面提到的,如果是多个应用运行在同一个系统上面,建议使用比垃圾回收器默认使用的线程数更少的线程数,使用选项是-XX:ParallelGCThreads=<n>.
  另外,由于大量的垃圾回收线程同时执行,垃圾回收可能会严重影响其他应用的性能。由于Java 6 Update 23之后,默认的垃圾回收线程是执行Runtime.availableProcessors()获得的,如果这个方法的返回值小于等于8,那么就用这个返回值,如果比8更大,那么就取这个值的5/8。如果运行多个应用,可以根据应用的情况来分配线程数,如果应用的消耗是相当的,那么就用CPU的内核数除以应用数得到每一个应用可以分配的线程。如果应用的load不相当,那么就可以根据应用的实际情况来衡量和分配。   下一步   如果你到这一步都还没有能够达到吞吐量的要求,那么可以尝试后面的“额外的性能选项”,如果还是无法达到,就只能修改应用或者JVM部署结构了。如果进行了修改应用或者修改了部署结构,你需要重新做前面的各个步骤。   可能会用到的一些边缘场景,下面一节介绍。   

热点排行