JVM

JVM调优

Posted by 杨一 on 2020-08-11

Jvm实战

GC Root对象的包括如下几种:

  1. Java虚拟机栈中的引用的对象 ;
  2. 方法区中的类静态属性引用的对象 ;
  3. 方法区中的常量引用的对象 ;
  4. 本地方法栈中JNI的引用的对象。
  • 而堆中的对象在正常情况下,一般是通过常量、全局变量、静态变量等间接引用堆中的对象,所以这些可以作为GC Root。

Minor gc是否会导致Stop The World(STW)?

  • 不管什么GC,都会发送stop the world,区别是发生的时间长短。而这个时间跟垃圾收集器又有关系,Serial、PartNew、Parallel Scavenge收集器无论是串行还是并行,都会挂起用户线程,而CMS和G1在并发标记时,是不会挂起用户线程,但其他时候一样会挂起用户线程,stop the world的时间相对来说小很多了。

Major gc什么时候会发生,它和Full gc的区别是什么?

  • 一次full gc将会对年轻代、老年代以及元空间、堆外内存进行垃圾回收。而触发Full GC的原因有很多:
    a、当年轻代晋升到老年代的对象大小比目前老年代剩余的空间大小还要大时,此时会触发Full GC;
    b、当老年代的空间使用率超过某阈值时,此时会触发Full GC;
    c、当元空间不足时(JDK1.7永久代不足),也会触发Full GC;
    d、当调用System.gc()也会安排一次Full GC;

查看GC日志
-XX:+PrintGC 输出 GC 日志
-XX:+PrintGCDetails 输出 GC 的详细日志
-XX:+PrintGCTimeStamps 输出 GC 的时间戳(以基准时间的形式)
-XX:+PrintGCDateStamps 输出 GC 的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在进行 GC 的前后打印出堆的信息
-Xloggc:…/logs/gc.log 日志文件的输出路径
-XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:./gclogs

JVM参数

  • -XX:InitialTenuringThreshol//对象年龄计数器最小值
  • -XX:MaxTenuringThreshold //对象年龄计数器最大值15
  • -XX:PetenureSizeThreshold //设置直接被分配到老年代的最大对象
  • -XX:+PrintFlagsFinal -version [| grep HeapSize] //查看堆内存配置的默认值
  • –XX:NewRatio= //设置青年代和老年代
  • -XX:+PrintTenuringDistribution //显示每次Minor GC时Survivor区中各个年龄段的对象的大小。
  • -XX:SurvivorRatio=4 //设置Eden和To Survivor、From Survivor 比例
  • -XX:+UseAdaptiveSizePolicy JDK1.8默认开启,动态调整 Java 堆中各个区域的大小以及进入老年代的年龄
  • java -jar -Xms1000m -Xmx4000m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heapdump.hprof -Xms1g -Xmx1g -XX:+PrintGCTimeStamps -XX:+PrintGCDetails -Xloggc:/tmp/heapTest.log heapTest-0.0.1-SNAPSHOT.jar //开启堆内存异常日志

JDK命令

  • jps -l
  • ps -ef|grep java
  • jstack 最常用的功能就是使用 jstack pid 命令查看线程堆栈信息,通常是结合 pidstat -p pid -t 一起查看具体线程的状态,也经常用来排查一些死锁的异常。
  • jstack 16079 > /usr/dump 将线程堆栈信息日志 dump 下来
  • jstat 可以监测 Java 应用程序的实时运行情况,包括堆内存信息以及垃圾回收信息。
  • jmap 来查看堆内存初始化配置信息以及堆内存的使用情况
  • jmap -heap [pid]

GC调优策略

  • 降低 Minor GC 频率
    • 通常情况下,由于新生代空间较小,Eden 区很快被填满,就会导致频繁 Minor GC,因此我们可以通过增大新生代空间来降低 Minor GC 的频率。
    • 复制对象的成本要远高于扫描成本。
  • 降低 Full GC 的频率
    • 频繁的 Full GC 会带来上下文切换,增加系统的性能开销。
    • 减少创建大对象
    • 增大堆内存空间
  • 选择合适的 GC 回收器
  • 要求每次操作的响应时间必须在 500ms 以内。这个时候我们一般会选择响应速度较快的 GC 回收器,CMS(Concurrent Mark Sweep)回收器和 G1 回收器都是不错的选择。
  • 对系统吞吐量有要求时,就可以选择 Parallel Scavenge 回收器来提高系统的吞吐量。
  • CMS 和 G1 回收器的响应速度快,Parallel Scavenge 回收器的吞吐量高。