JVM

常用的JVM参数及GC信息参数的意义

王守钰 2020-08-10 13:08:38

常用参数

-Xms

—Xms等价于-XX:InitialHeapSize,初始大小内存默认为物理内存的1/64。

long totalMemory = Runtime.getRuntime().totalMemory();
System.out.print("totalMemory(-Xms) = " +  totalMemory);
System.out.println("B\t" + totalMemory/1024/1024 + "MB");

执行结果

totalMemory(-Xms) = 128974848B	123MB

本机的物理内存是8G,8G的1/64是128MB,计算下来也是差不多的。

-Xmx

-Xmx等价于-XX:MaxHeapSize,最大分配内存,默认为物理内存的1/4

long maxMemory = Runtime.getRuntime().maxMemory();
System.out.print("maxMemory(-Xmx) = " +  maxMemory);
System.out.println("B\t" + maxMemory/1024/1024 + "MB");

执行结果

maxMemory(-Xmx) = 1908932608B	1820MB

本机的物理内存是8G,8G的1/4是2048MB,计算下来也是差不多的。

-Xss

-Xss等价于-XX:ThreadStackSize,设置单个线程栈大小,一般大小为128KB~1024KB,这个参数的默认值的默认值取决于操作系统,一般默认值为1024KB。

jinfo -flag ThreadStackSize 15907
-XX:ThreadStackSize=1024

-Xmn

年轻代大小,一般来说不需要调整,使用系统默认。

-XX:MetaspaceSize

元空间的本质和永久代累死,都是对JVM规范中方法区的实现。不过元空间与永久代之间最大的区别在于:**元空间并不在虚拟机中,而是在本地内存。**因此,默认情况下,元空间的大小仅受本地内存限制。

jinfo -flag MetaspaceSize 17473
-XX:MetaspaceSize=21807104

默认的元空间大小大概为21MB左右。

-XX:+PrintGCDetails

运行的时候设置参数-Xms10m -Xmx10m -XX:+PrintGCDetails

[GC (Allocation Failure) [PSYoungGen: 2045K->511K(2560K)] 2045K->737K(9728K), 0.0059457 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2477K->511K(2560K)] 2703K->1354K(9728K), 0.0017421 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 2559K->512K(2560K)] 3402K->1476K(9728K), 0.0009236 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 1629K->512K(2560K)] 2594K->1564K(9728K), 0.0008879 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[GC (Allocation Failure) [PSYoungGen: 512K->512K(2560K)] 1564K->1588K(9728K), 0.0011152 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 512K->0K(2560K)] [ParOldGen: 1076K->1090K(7168K)] 1588K->1090K(9728K), [Metaspace: 3008K->3008K(1056768K)], 0.0097471 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
[GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] 1090K->1090K(8704K), 0.0004642 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 
[Full GC (Allocation Failure) [PSYoungGen: 0K->0K(1536K)] [ParOldGen: 1090K->1075K(7168K)] 1090K->1075K(8704K), [Metaspace: 3008K->3008K(1056768K)], 0.0137262 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 
Heap
 PSYoungGen      total 1536K, used 73K [0x00000007bfd00000, 0x00000007c0000000, 0x00000007c0000000)
  eden space 1024K, 7% used [0x00000007bfd00000,0x00000007bfd12740,0x00000007bfe00000)
  from space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
  to   space 1024K, 0% used [0x00000007bfe00000,0x00000007bfe00000,0x00000007bff00000)
 ParOldGen       total 7168K, used 1075K [0x00000007bf600000, 0x00000007bfd00000, 0x00000007bfd00000)
  object space 7168K, 14% used [0x00000007bf600000,0x00000007bf70cc90,0x00000007bfd00000)
 Metaspace       used 3045K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 318K, capacity 392K, committed 512K, reserved 1048576K
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.wangshouyu.gc.HelloGc.main(HelloGc.java:14)

GC信息查看阅读

[GC (Allocation Failure) [PSYoungGen: 2045K->511K(2560K)] 2045K->737K(9728K), 0.0059457 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 

younggc解析
image

[Full GC [PSYoungGen: 512K->0K(2560K)] [ParOldGen: 1076K->1090K(7168K)] 1588K->1090K(9728K), [Metaspace: 3008K->3008K(1056768K)], 0.0097471 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 

fullgc解析
image

-XX:SurvivorRatio

设置新生代中的Eden和S0/S1区的空间比例,默认-XX:SurvivorRatio=8,Eden:S0:S1=8:1:1。加入设置-XX:SurvivorRatio=4,Eden:S0:S1=4:1:1

Heap
 PSYoungGen      total 39424K, used 9311K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
  eden space 35328K, 26% used [0x0000000795580000,0x0000000795e97ec0,0x0000000797800000)
  from space 4096K, 0% used [0x0000000797c00000,0x0000000797c00000,0x0000000798000000)
  to   space 4096K, 0% used [0x0000000797800000,0x0000000797800000,0x0000000797c00000)
 ParOldGen       total 87552K, used 0K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
  object space 87552K, 0% used [0x0000000740000000,0x0000000740000000,0x0000000745580000)
 Metaspace       used 3014K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 315K, capacity 392K, committed 512K, reserved 1048576K

Eden=35328K,from=4096K,to=4096K计算出比例大致为8:1:1。修改-XX:SurvivorRatio=4

Heap
 PSYoungGen      total 36352K, used 9115K [0x0000000795580000, 0x0000000798000000, 0x00000007c0000000)
  eden space 29184K, 31% used [0x0000000795580000,0x0000000795e66f88,0x0000000797200000)
  from space 7168K, 0% used [0x0000000797900000,0x0000000797900000,0x0000000798000000)
  to   space 7168K, 0% used [0x0000000797200000,0x0000000797200000,0x0000000797900000)
 ParOldGen       total 87552K, used 0K [0x0000000740000000, 0x0000000745580000, 0x0000000795580000)
  object space 87552K, 0% used [0x0000000740000000,0x0000000740000000,0x0000000745580000)
 Metaspace       used 3014K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 315K, capacity 392K, committed 512K, reserved 1048576K

eden=29184K,from=7168K,to=7168K,计算比例大致为4:1:1

-XX:NewRatio

配置年轻代与老年代在堆中的占比。默认:-XX:NewRatio=2年轻代占1,老年代占2,年轻代占整个堆的1/3。例如-XX:NewRatio=4年轻代占1,老年代占4,年轻代占整个堆的1/5。NewRatio的值就是设置老年代的占比,剩下的1给年轻代。使用SerialGC回收器执行-XX:+PrintGCDetails -XX:+UseSerialGC

Heap
 def new generation   total 39296K, used 9223K [0x0000000740000000, 0x0000000742aa0000, 0x000000076aaa0000)
  eden space 34944K,  26% used [0x0000000740000000, 0x0000000740901c28, 0x0000000742220000)
  from space 4352K,   0% used [0x0000000742220000, 0x0000000742220000, 0x0000000742660000)
  to   space 4352K,   0% used [0x0000000742660000, 0x0000000742660000, 0x0000000742aa0000)
 tenured generation   total 87424K, used 0K [0x000000076aaa0000, 0x0000000770000000, 0x00000007c0000000)
   the space 87424K,   0% used [0x000000076aaa0000, 0x000000076aaa0000, 0x000000076aaa0200, 0x0000000770000000)
 Metaspace       used 3014K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 315K, capacity 392K, committed 512K, reserved 1048576K

new generation=39296K,tenured generation=87424K,算下来年轻代和老年代的比例大概也就是1:2,修改比例-XX:+PrintGCDetails -XX:+UseSerialGC -XX:NewRatio=4

Heap
 def new generation   total 23616K, used 8488K [0x0000000740000000, 0x0000000741990000, 0x0000000759990000)
  eden space 21056K,  40% used [0x0000000740000000, 0x000000074084a290, 0x0000000741490000)
  from space 2560K,   0% used [0x0000000741490000, 0x0000000741490000, 0x0000000741710000)
  to   space 2560K,   0% used [0x0000000741710000, 0x0000000741710000, 0x0000000741990000)
 tenured generation   total 104896K, used 0K [0x0000000759990000, 0x0000000760000000, 0x00000007c0000000)
   the space 104896K,   0% used [0x0000000759990000, 0x0000000759990000, 0x0000000759990200, 0x0000000760000000)
 Metaspace       used 3014K, capacity 4556K, committed 4864K, reserved 1056768K
  class space    used 315K, capacity 392K, committed 512K, reserved 1048576K

new generation=23616K,tenured generation=104896K,年轻代和老年代的比例大概也就是1:4

-XX:MaxTenuringThreshold

从young区到old区经历多少次回收,垃圾最大年龄,默认值是15。-XX:MaxTenuringThreshold=0代表设置垃圾最大年龄,如果设置为0的话,则年轻代对象不经过Survivor区,直接进入老年代,对于老年代校对的应用可以提高效率。如果将此值设置一个比较大的值,则年轻代对象会在Survivor区进行多次复制,这样可以增加对象在年轻代的存活时间,增加在年轻代被回收的概率。设置-XX:+PrintGCDetails -XX:+UseSerialGC -XX:MaxTenuringThreshold=16

MaxTenuringThreshold of 16 is invalid; must be between 0 and 15
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.

我们可以看到MaxTenuringThreshold设置值的范围应该在0-15之间。