3、GC常用参数
1.堆分配参数
-Xms5m(初始化堆空间) -Xmx20m(最大堆空间) -XX:+PrintGCDetails(详细GC日志) -XX:+UseSerialGC(串行收集算法,Hotspot默认是并行的) -XX:+PrintCommandLineFlags (打印这些命令行)
package com.caolihua; public class Test01 { public static void main(String[] args) { //-Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags //查看GC信息 System.out.println("max memory:" + Runtime.getRuntime().maxMemory()/(1024*1024.0)); System.out.println("free memory:" + Runtime.getRuntime().freeMemory()/(1024*1024.0)); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()/(1024*1024.0)); byte[] b1 = new byte[1*1024*1024]; System.out.println("分配了1M"); System.out.println("max memory:" + Runtime.getRuntime().maxMemory()/(1024*1024.0)); System.out.println("free memory:" + Runtime.getRuntime().freeMemory()/(1024*1024.0)); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()/(1024*1024.0)); byte[] b2 = new byte[4*1024*1024]; System.out.println("分配了4M"); System.out.println("max memory:" + Runtime.getRuntime().maxMemory()/(1024*1024.0)); System.out.println("free memory:" + Runtime.getRuntime().freeMemory()/(1024*1024.0)); System.out.println("total memory:" + Runtime.getRuntime().totalMemory()/(1024*1024.0)); } }
打印结果输出:
-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC max memory:19.375 free memory:5.007911682128906 total memory:5.8125 [GC (Allocation Failure) [DefNew: 823K->191K(1856K), 0.0037429 secs] 823K->556K(5952K), 0.0038460 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 分配了1M max memory:19.375 free memory:4.2360382080078125 total memory:5.8125 [GC (Allocation Failure) [DefNew: 1249K->0K(1856K), 0.0032904 secs][Tenured: 1581K->1581K(4096K), 0.0056323 secs] 1614K->1581K(5952K), [Metaspace: 2600K->2600K(1056768K)], 0.0090417 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 分配了4M max memory:19.375 free memory:4.301551818847656 total memory:9.87890625 Heap
def new(1920K)=eden(1728K)+from/to(192K) def new generation(不同收集算法,这里新生代写法不一样,默认是串行) total 1920K, used 69K [0x00000000fec00000, 0x00000000fee10000, 0x00000000ff2a0000) //这里计算结果要略微小于总的边界差值空间 eden space 1728K, 3% used [0x00000000fec00000, 0x00000000fec11440, 0x00000000fedb0000)//分别表示:上(a)、当前(b)、最大边界(c),1728K=转10进制(c-a)/1024 from space 192K, 0% used [0x00000000fedb0000, 0x00000000fedb0000, 0x00000000fede0000) to space 192K, 0% used [0x00000000fede0000, 0x00000000fede0000, 0x00000000fee10000) tenured generation total 8196K, used 5677K [0x00000000ff2a0000, 0x00000000ffaa1000, 0x0000000100000000) the space 8196K, 69% used [0x00000000ff2a0000, 0x00000000ff82b448, 0x00000000ff82b600, 0x00000000ffaa1000) Metaspace used 2607K, capacity 4486K, committed 4864K, reserved 1056768K class space used 278K, capacity 386K, committed 512K, reserved 1048576K
JVM内存分配情况:
max memory:19.375 JVM最大内存
free memory:4.973960876464844 total里面的,未被使用的内存
total memory:5.8125 JVM已经申请到的内存
也就是说:剩余的可用内存是max-total+free
2. 当前java项目根目录生成log日志文件
-Xloggc:log/gc.log
3.每发生一次GC,打印GC前后的堆内存变化;PrintGCDetails是程序结束后,打印最后一次
-XX:+PrintHeapAtGC
4.监控类加载
-XX:+TraceClassLoading
[Opened C:\Program Files\Java\jdk1.8.0_31\jre\lib\rt.jar] [Loaded java.lang.Object from C:\Program Files\Java\jdk1.8.0_31\jre\lib\rt.jar] [Loaded java.io.Serializable from C:\Program Files\Java\jdk1.8.0_31\jre\lib\rt.jar] [Loaded java.lang.Comparable from C:\Program Files\Java\jdk1.8.0_31\jre\lib\rt.jar] [Loaded java.lang.CharSequence from C:\Program Files\Java\jdk1.8.0_31\jre\lib\rt.jar] [Loaded java.lang.String from C:\Program Files\Java\jdk1.8.0_31\jre\lib\rt.jar]
5.程序运行过程中,按下Ctrl+Break后,打印类的信息
-XX:+PrintClassHistogram
6.新生代(eden,from,to)+老年代=堆内存 //(from空间=to空间)
Xmn1m 设置新生代的空间,XX:SurvivorRatio,设置新生代伊甸园和from或to区间的比值,可观察以下结果。
-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
package com.caolihua; public class Test02 { public static void main(String[] args) { byte[] b = null; //连续向系统申请空间,总共shenqing for(int i = 0 ; i <10; i ++){ b = new byte[1*1024*1024]; } } }
打印结果:
Heap
def new generation total 768K, used 497K [0x00000000fec00000, 0x00000000fed00000, 0x00000000fed00000)
eden space 512K, 47% used [0x00000000fec00000, 0x00000000fec3c5e0, 0x00000000fec80000)
from space 256K, 99% used [0x00000000fecc0000, 0x00000000fecffff8, 0x00000000fed00000)
to space 256K, 0% used [0x00000000fec80000, 0x00000000fec80000, 0x00000000fecc0000)
tenured generation total 19456K, used 10409K [0x00000000fed00000, 0x0000000100000000, 0x0000000100000000)
the space 19456K, 53% used [0x00000000fed00000, 0x00000000ff72a440, 0x00000000ff72a600, 0x0000000100000000)
Metaspace used 2553K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 273K, capacity 386K, committed 512K, reserved 1048576K
--------------------------------------------
XX:NewRatio:设置老年代和新生代空间比值
-Xms20m -Xmx20m -XX:NewRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
Heap
def new generation total 6144K, used 1079K [0x00000000fec00000, 0x00000000ff2a0000, 0x00000000ff2a0000)
eden space 5504K, 19% used [0x00000000fec00000, 0x00000000fed0ddb0, 0x00000000ff160000)
from space 640K, 0% used [0x00000000ff160000, 0x00000000ff160000, 0x00000000ff200000)
to space 640K, 0% used [0x00000000ff200000, 0x00000000ff200000, 0x00000000ff2a0000)
tenured generation total 13696K, used 2564K [0x00000000ff2a0000, 0x0000000100000000, 0x0000000100000000)
the space 13696K, 18% used [0x00000000ff2a0000, 0x00000000ff521220, 0x00000000ff521400, 0x0000000100000000)
Metaspace used 2553K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 273K, capacity 386K, committed 512K, reserved 1048576K
大伙可以算一下这个比例是否符合。
结论:新生代的大小一般设置是整个JVM堆空间的1/3~1/4左右,新生代过小,会引起频繁的GC,浪费性能;具体性能测试还是要根据你的程序,常驻内存的占多少?应该会有这种测试软件吧?
7.堆内存溢出package com.calihua;
import java.util.Vector; public class Test03 { public static void main(String[] args) { //设置为1M,会堆内存溢出,频繁gc但是还是会超过1m,设置为4M,虽然小于5M,但是频繁GC,使得最大超不过4M,所以不会溢出
//
//-XX:HeapDumpPath=d:/Test03.dump :生成报错文件,可以用工具去打开查看,但是有更方便的工具总体宏观把控,所以一般不这样搞。
//-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump -XX:+PrintGCDetails //堆内存溢出
//共创建5M
Vector v = new Vector(); for(int i=0; i < 5; i ++){ v.add(new Byte[1*1024*1024]); } } }
8.栈空间设置:栈空间决定了一个线程栈的大小,即线程纵向调用最大深度。
package com.calihua; public class Test04 { //-Xss1m //-Xss5m //栈调用深度 private static int count; public static void recursion(){ count++; recursion(); } public static void main(String[] args){ try { recursion(); } catch (Throwable t) { System.out.println("调用最大深入:" + count); t.printStackTrace(); } } }
报错:java.lang.StackOverflowError
9.方法区(永久区):亦所有线程共享区域,保存系统类信息,默认-XX:MaxPermSize=64M,也可以自定义设置,如果系统产生很多种类,需增大该空间
10.直接内存区:NIO的buffer区域,-XX:MaxDirectMemorySize 用Mycat、Socket通信时,要注意此类错误信息。
据说是比堆空间读写速度还要快?
浙公网安备 33010602011771号