Java虚拟机日志与参数(2)

参数-XX:SurvivorRatio用于设置新生代中eden空间和from/to空间的比例。它的含义是:-XX:SurvivorRatio=eden/from=eden/to。如下代码可以观察不同的参数对GC影响
/**
 * 默认VM参数:-Xms20m -Xmx20m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
 * 修改 -Xmn参数
 */
public static void main(String[] args) {
    byte[] a = null;
    for(int i=0; i<10; i++) {
        a = new byte[1024*1024];
    }         
}

1.-Xmn1m时,GC日志如下。eden区为1M*(2/(2+2))=0.5M,from=to=0.25M,新生代可使用内存eden + from=768K(如下total 768K)。eden区无法容纳1M的数据,所以触发了一次新生代的GC,GC后还是无法容纳1M数据,导致数据最终都分配在老年代,老年代最终占用10413K。
    [GC (Allocation Failure) [DefNew: 507K->256K(768K), 0.0009151 secs] 507K->428K(20224K), 0.0009609 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
    Heap
    def new generation  total 768K, used 514K [0x00000000fec00000, 0x00000000fed00000, 0x00000000fed00000)
      eden space 512K,  50% used [0x00000000fec00000, 0x00000000fec40b40, 0x00000000fec80000)
      from space 256K, 100% used [0x00000000fecc0000, 0x00000000fed00000, 0x00000000fed00000)
      to  space 256K,  0% used [0x00000000fec80000, 0x00000000fec80000, 0x00000000fecc0000)
    tenured generation  total 19456K, used 10413K [0x00000000fed00000, 0x0000000100000000, 0x0000000100000000)
      the space 19456K,  53% used [0x00000000fed00000, 0x00000000ff72b448, 0x00000000ff72b600, 0x0000000100000000)
    Metaspace      used 2686K, capacity 4486K, committed 4864K, reserved 1056768K
      class space    used 286K, capacity 386K, committed 512K, reserved 1048576K

1.-Xmn7m时,GC日志如下。eden=3.5M=3584K,from=to=1792K,新生代可以内存5376K。当初始化第三个数组前的时候时,eden区已经使用2886K,还剩下692K(3584-2886),明显不够分配,触发一次Minor GC。接下来初始化到第六个数组前时,eden区已使用3142K(4695-1553),还剩下442K(3584-3142),也要触发Minor GC。
[GC (Allocation Failure) [DefNew: 2886K->1553K(5376K), 0.0013204 secs] 2886K->1553K(18688K), 0.0013493 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [DefNew: 4695K->1024K(5376K), 0.0010302 secs] 4695K->1552K(18688K), 0.0010404 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
[GC (Allocation Failure) [DefNew: 4157K->1024K(5376K), 0.0002867 secs] 4686K->1552K(18688K), 0.0002951 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
Heap
 def new generation  total 5376K, used 3208K [0x00000000fec00000, 0x00000000ff300000, 0x00000000ff300000)
  eden space 3584K,  60% used [0x00000000fec00000, 0x00000000fee223a0, 0x00000000fef80000)
  from space 1792K,  57% used [0x00000000ff140000, 0x00000000ff240010, 0x00000000ff300000)
  to  space 1792K,  0% used [0x00000000fef80000, 0x00000000fef80000, 0x00000000ff140000)
 tenured generation  total 13312K, used 528K [0x00000000ff300000, 0x0000000100000000, 0x0000000100000000)
  the space 13312K,  3% used [0x00000000ff300000, 0x00000000ff384148, 0x00000000ff384200, 0x0000000100000000)
 Metaspace      used 2651K, capacity 4486K, committed 4864K, reserved 1056768K
  class space    used 285K, capacity 386K, committed 512K, reserved 1048576K

3|0非堆参数配置

除了堆内存,虚拟机还有一些内存用于方法区、栈和直接内存的使用。和堆内存相比,这些内存空间和应用程序的关系不那么密切,但是合理的配置也对系统的性能和稳定有着重要的作用。

3|1方法区配置

方法区主要存放类的元数据信息。在JDK1.6和JDK1.7的版本中,可以使用-XX:PermSize和-XX:MaxPermSize配置永久代大小。在JDK1.8中,永久代被彻底移除,使用心得元数据区存放类的元数据。默认情况元数据区只接受系统的可用内存限制,但是依然可以是参数-XX:MaxMetaspaceSize指定元数据区大小。

3|2栈配置配置

栈是每个线程的私有空间,在虚拟机中可以用-Xss参数来指定线程栈的大小。
public class StackDeepTest {

private static int count = 0;

public static void recursionCall() {
        count ++;
        recursionCall();
    }

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

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