虚拟机参数调优

前段时间又看了一遍《深入理解Java虚拟机》,感觉比以前看的理解程度多了一些。找一些以前的关于虚拟机参数的笔记内容写下来。

虚拟机有很多种,一般应用的都是HotSpot虚拟机,所以大家讨论的也都是针对这款虚拟机。不同的虚拟机实现是不一样的。

运行时会根据热点程序,进行不同程度的优化编译,不是编译一次就完事的。高级编译时会引入大胆的优化策略,也会留逃生门。

一,注意事项

  • 虚拟机在64位机器上,内存大于32G时,会放弃指针压缩,导致内存很大浪费,所以内存最好控制在4-32G。
  • 使用Jinfo观察运行时的所有参数;
  • jstack查看线程信息;jmap生成dump文件;jstat观察运行时的类加载、编译、回收内容。
  • 使用MAT可视化分析线上Dump文件。由于文件一般比较大,所以分析时比较耗内存,也比较慢。
  • 出现内存溢出的问题时,仔细看一下报错内容,在不同区域内存报错的类型或提示是不一样的。

二,垃圾收集器

  • 目前HotSpot使用的是分代收集法。相关策略有Serial、ParNew、Parallel、CMS、G1等等。
  • NewRatio参数设置新生代和老生代的内存比例。
  • 新生代Eden和Survivor的默认比例是8:1,即SurvivorRatio为1。
  • Windows和Linux(CPU只有一个核)时,JVM默认运行的模式是Client,此时默认的收集器是Serial;在Linux多核时默认运行的模式是Server,收集器使用的是Parallel。
  • 可通过-XX:Use***GC来修改收集器类型,不同的收集器类型还有详细的相关参数进行微调。
  • 在服务器上,使用CMS已经非常成熟了,很多中间件都是使用的CMS回收。

三,其他参数

  • HeapDumpOnOutOfMemoryError和HeapDumpPath参数,用以在发生OOM异常时保存当时Dump。
  • PrintGC和PrintGC***参数可以在每次垃圾回收时输出日志,包含回收各部分内存大小和消耗时间。
  • 一般新生代的收集时间为几毫秒,老生代的回收时间达到一百多毫秒。异常状况时,数值会变大很多。

四,收集器微调

1.  SerialGC :
        -XX:+UseSerialGC
            就是Young区和old区都使用serial 垃圾回收算法。
2.  ParNewGC
        -XX:+UseParNewGC
            设置年轻代为多线程收集。可与CMS收集同时使用。在serial基础上实现的多线程收集器。
            指定在 New Generation 使用 parallel collector, 是 UseParallelGC 的 gc 的升级版本 , 有更好的性能或者优点。
        -XX:ParallelGCThreads 限制线程数量
3.  ParallelGC
        -XX:+UseParallelGC
            选择垃圾收集器为并行收集器。此配置仅对年轻代有效。可以同时并行多个垃圾收集线程,但此时用户线程必须停止。新生代使用parallel并行收集,会暂停app threads,同时启动多个垃圾回收thread。不能和CMS一起使用。一般来说后台系统任务使用此方式。

4.  CMS
        -XX:+UseConcMarkSweepGC
            Young区:可以使用普通的或者parallel 垃圾回收算法,由参数 -XX:+UseParNewGC来控制。Old 区:使用CMS
        -XX:CMSInitiatingOccupancyFraction=75
            这个值指定了老生代使用到成么程度后进行回收。
        -XX:+UseCMSInitiatingOccupancyOnly
            如果没有使用此参数,那么HotSpot VM只是利用上述参数值来启动第一次CMS垃圾回收,后面都是使用HotSpot VM自动计算出来的值。
        -XX:+ UseCMSCompactAtFullCollection Full GC后,进行一次碎片整理;整理过程是独占的,会引起停顿时间变长
        -XX:+CMSFullGCsBeforeCompaction  设置进行几次Full GC后,进行一次碎片整理
        -XX:ParallelCMSThreads  设定CMS的线程数量

你可能感兴趣的:(Java虚拟机)