第二篇 jvm常用参数

不同的jvm参数可以在gc信息中显示出不同的内容,我们先来学习以下简单的gc信息.

  

 开启-XX:+PrintGCDetails参数,运行java程序查看gc信息

 

[GC (System.gc()) [PSYoungGen: 523K->368K(4608K)] 523K->376K(15872K(可用堆大小)), 0.0014747 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
[Full GC (System.gc()) [PSYoungGen: 368K->0K(4608K)] [ParOldGen: 8K->297K(11264K)] 376K->297K(15872K), [Metaspace: 2643K->2643K(1056768K)], 
0.0043307 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 

   

Heap
   PSYoungGen(新生代大小)      total 4608K, used 0K [0x00000007bfb00000, 0x00000007c0000000, 0x00000007c0000000]
    (三个16进制数据分别代表下界,当前上界,上界)
    上界-下届= 堆空间的最大值; 当前上界-下界=已为虚拟机分配的空间;上界=当前上界  说明已经没有扩展空间了
     eden space 4096K, 0% used [0x00000007bfb00000,0x00000007bfb00388,0x00000007bff00000)
     from space 512K, 0% used [0x00000007bff00000,0x00000007bff00000,0x00000007bff80000)
      to   space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000]
   ParOldGen (老年代大小)      total 11264K, used 297K [0x00000007bf000000, 0x00000007bfb00000, 0x00000007bfb00000)
      object space 11264K, 2% used [0x00000007bf000000,0x00000007bf04a698,0x00000007bfb00000]
   Metaspace ((方法区大小))      used 2649K, capacity 4486K, committed 4864K, reserved 1056768K
      class space    used 287K, capacity 386K, committed 512K, reserved 1048576K

 GC  信息的相关参数

    

   -XX:+PrintHeapAtGC,可以查看GC回收前后的堆信息

   -XX:+PrintGCTimeStamps   打印GC发生的时间戳,相对于虚拟机的启动时间

   -XX:+PrintReferenceGc 可以查看软饮用,弱引用,虚引用和Finallize队列

   -XLoggc:log/gc.log  指定gc日志以文件形式输出

   -verbose:gc 开启gc跟踪 

   -verbose:class 跟踪类的加载和卸载等价于-XX:+TraceClassLoading和

   -XX:+TraceClassUnloading

   -XX:+PrintCommandLineFlags可以打印出虚拟机的显式和隐式参数

 

 新生代老生代参数测试

     

-Xms:最小堆内存(初始分配的)

-Xmx:最大堆内存(超过这个就会内存溢出)

-Xmn:新生代的大小

-XX:SurvivorRatio  设置eden空间和from/to空间的比例大小

-XX:NewRatio=老年代/新生代

    

 

jvm参数:-Xms15m -Xmx15m –Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails

public static void main(String[] args) throws InterruptedException {
    byte[] b  = null;
   for(inti = 0 ;i< 10 ;i++){

     b = newbyte[1*1024*1024];
  }
}

  SurvivorRatio = eden/from =2;

  可用的=eden+from

  总共的=eden+from+to

   由于eden只有512k,不足以分配1m的空间,所以所有的都分配在老年代

   

[GC (Allocation Failure) [PSYoungGen: 512K->432K(1024K)] 512K->440K(15872K), 0.0014905 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Heap
PSYoungGen      total 1024K, used 457K [0x00000007bfe80000, 0x00000007c0000000, 0x00000007c0000000)
   eden space 512K, 5% used [0x00000007bfe80000,0x00000007bfe86798,0x00000007bff00000)
   from space 512K, 84% used [0x00000007bff00000,0x00000007bff6c010,0x00000007bff80000)
   to   space 512K, 0% used [0x00000007bff80000,0x00000007bff80000,0x00000007c0000000)
ParOldGen       total 14848K, used 10248K [0x00000007bf000000, 0x00000007bfe80000, 0x00000007bfe80000)
   object space 14848K, 69% used [0x00000007bf000000,0x00000007bfa020a0,0x00000007bfe80000)
Metaspace       used 2645K, capacity 4486K, committed 4864K, reserved 1056768K
   class space    used 286K, capacity 386K, committed 512K, reserved 1048576K

   -Xms20m -Xmx20m -Xmn6m -XX:SurvivorRatio=2 -XX:+PrintGCDetails

    如果eden有足够的空间,所有的内存都会在eden分配

  -Xms20m -Xmx20m -XX:NewRatio=2 -XX:+PrintGCDetails

  这样新生代为6m  老年代为13m,from空间为600k,新生代回收的时候需要老年代进行空间担保.

 

 

  堆溢出的处理

      如果堆空间不足,就会outofmemory:Java Heap Space.使用参数-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/Users/zcf1/Downloads/test.dump

     导出发生内存溢出时,整个堆的信息.“-XX:OutOfMemoryError=脚本路径 %p”

     脚本内容(进程信息)

     …bin/jstack –F %l > 路径/a.txt

 

  直接内存配置

       -XX:MaxDirectMemorySize,默认是-Xmx,达到MaxDirectMemorySize时候就会触发垃圾回收。

        直接内存的优势在于读写速度快于堆内存,下面程序用来测试直接内存和堆内存性能的比较.

       

public class AccessDirectBuffer {
    public static void directAccess(){
    	long begin = System.currentTimeMillis();
    	ByteBuffer b = ByteBuffer.allocateDirect(500);
    	for(int i = 0 ;i< 10000000;i++){
    		for(int j =0 ;j< 99;j++){
    			b.putInt(j);
    		}
    		b.flip();
    		for(int j =0 ;j< 99;j++){
    			b.getInt();
    		}
    		b.clear();
    	}
    	long end = System.currentTimeMillis();
    	System.out.println("Direct:"+(end-begin));
    }
    public static void bufferAccess(){
    	long begin = System.currentTimeMillis();
    	ByteBuffer b = ByteBuffer.allocate(500);
    	for(int i = 0 ;i< 10000000;i++){
    		for(int j =0 ;j< 99;j++){
    			b.putInt(j);
    		}
    		b.flip();
    		for(int j =0 ;j< 99;j++){
    			b.getInt();
    		}
    		b.clear();
    	}
    	long end = System.currentTimeMillis();
    	System.out.println("buffer:"+(end-begin));
    }
    public static void main(String[] args) {
		bufferAccess();
		directAccess();
	}
}

 

猜你喜欢

转载自zcf9916.iteye.com/blog/2407795