Hotspot优化指南(上)

  一次偶然,博主在浏览docs.oracle.com/javase的时候发现了《Hotspot虚拟机垃圾收集调优指南》这篇文档。内心百感交集,之前在看完了周志明的《深入理解Java虚拟机 JVM高级特性与最佳实践(第二版)》也有比较长篇的学习记录博客发表。不过那也是基于JDK7进行编写的。后续的8、9、10都没有找到好的关于JVM更加新的好的内容。由于性子懒惰加上本身英语不佳,一直都没上官网进行相关研究。本篇文章就是博主在研读这篇文档的时候所记录,也是基于现如今最流行的JDK8相关内容,欢迎指正。

  在简介中文章指出垃圾收集器(GC)是一个内存管理工具,它通过了以下三点实现了内存管理:
    1、将对象分配给新生代和晋升老的对象到老年代
    2、并发标记阶段在老年代找到存活的对象。当Java堆占用率超过默认阈值时,Java Hotspot虚拟机会触发标记阶段。
    3、通过并行复制压缩存活的对象来恢复空闲内存,
  文中通过一个图展示了随着处理器的增多不同GC时间下吞吐量的变化(如图一),从此图中我们可以分析出的以下结论:

Hotspot优化指南(上)

(图一)

 


    1、在处理器比较少的情况下(少于10?),设置越高的GC占用时间百分比便越会导致吞吐量急剧下降。
    2、在小型系统上可以忽略的速度问题会成为大型系统上面的瓶颈,选择合适的垃圾收集器和必要的调优是值得的

  Ergonomics就是JVM哈垃圾收集器调优的过程,比如基于行为的调优,提高应用程序的性能。JVM为垃圾收集器、堆大小和即时编译器提供平台相关的默认的配置。当你需要更少的命令行调优的时候,这些选项可以匹配不同类型的应用。另外,可以基于行为动态调整堆的大小以满足应用程序的特定行为。这一节描述了这些默认选择和基于行为的调优。

  以下是GC、堆和运行时编译器的默认选择说明: 

    一个被定义为Server-Class所在机器的要求:
      1、两个或以上的处理器
      2、2GB或以上的物理内存
    在Server-Class机器上,一下是默认选项:
      1、吞吐量优先垃圾收集器
      2、堆初始化大小为物理内存的1/64,最大为1GB
      3、最大的堆大小范围为物理内存的1/4到1GB
      4、Server模式的运行时编译器
    上面的定义适用于除window 32位系统以外的其他所有平台。默认运行时编译器详情可以查看。

  基于行为的调优:

    对并行收集器来说,JavaSE基于特定行为的基础上提供了两个垃圾收集调优参数:最大暂停时间应用程序的吞吐量

    最大暂停时间:暂停时间是垃圾收集器停止应用程序并恢复已不再使用的空间的持续时间。最大暂停时间目标的目的是限制这些暂停时间最长的时间。通过命令行 -XX:MaxGCPauseMillis=<nnn>来指定。通过这个参数的设置,垃圾收集器会调整堆的大小和其他相关参数让暂停时间尽量接近所设置的最大暂停时间。默认情况下,如果没有最大暂停时间这些调整可能导致频繁GC从而降低应用程序的吞吐量

    吞吐量:吞吐量是由垃圾收集时间和应用程序时间来衡量的。通过-XX:GCTimeRatio=<nnn>来设置吞吐量的大小。比如 -XX:GCTimeRatio=19表示垃圾收集的时间占总应用时间的1/20或者5%。JVM为垃圾收集器、堆大小和即时编译器提供平台相关的默认的配置。当你需要更少的命令行调优的时候,这些选项可以匹配不同类型的应用。另外,可以基于行为动态调整堆的大小以满足应用程序的特定行为。这一节描述了这些默认选择和基于行为的调优。垃圾收集的时间是新生代和老年代GC时间的和。如果吞吐量目标没有实现的话,为了让应用程序运行时间在与垃圾收集时间所占比重增加,JVM会增大新生代和老年代的大小。

    如果达到了吞吐量和最大暂停时间目标,那么垃圾收集器就会减少堆的大小,直到让一个目标(总是吞吐量目标)无法满足。没有达到的目标就会被解决(放弃?)

    调优策略   

      1、不要设置堆的最大值除非你知道你需要一个比默认最大堆大小更大的堆。选择一个对你的应用来说足够了的吞吐量目标。
      为了实现设定的吞吐量,堆将增大或缩减到一个大小。应用程序行为的改变会导致堆的增长或收缩。例如,如果应用程序开始以更高的速率分配,堆将会增长以保持相同的吞吐量。
      2、如果堆增长到最大值且设置吞吐量目标没有达到,那么最大堆大小对于吞吐量目标来说太小了。将最大堆大小设置为接近于平台的总物理内存的值,但不会导致应用程序的交换。再次执行应用程序。如果吞吐量目标仍然没有满足,那么应用程序时间的目标对于平台上可用的内存来说太高了。
      3、如果能够满足吞吐量目标,但是有一些暂停太长,然后选择一个最大的暂停时间目标。选择一个最大的暂停时间目标可能意味着您的吞吐量目标将无法满足,因此选择对于应用程序来说是可接受的折衷方案。
      4、通常情况下,堆的大小会随着垃圾收集器试图满足相互竞争的目标而振荡。即使应用程序已经达到了稳定状态,这也是正确的。实现吞吐量目标(可能需要更大的堆)的压力与最大暂停时间和最小内存占用(两者都可能需要一个小堆)的目标竞争。

  分代收集算法的依据便是:绝大部分新产生的对象应该要被回收。如下图二,所展示的对象生命周期的典型分布。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zywjdd.html