在虚拟机运行的过程中,如果可以跟踪系统的运行状态,那么对于问题的鼓掌排查会有一定的帮助。因此,虚拟机提供了一些跟踪系统状态的参数,使用给定的参数执行java虚拟机,就可以在系统运行时打印相关日志,用于分析实际问题。虚拟机参数配置,其实主要围绕着堆、栈、方法区进行配置。
//查看GC信息
System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
byte[] b1 = new byte[1*1024*1024];
System.out.println("分配了1M");
System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
byte[] b2 = new byte[4*1024*1024];
System.out.println("分配了4M");
System.out.println("max memory:" + Runtime.getRuntime().maxMemory());
System.out.println("free memory:" + Runtime.getRuntime().freeMemory());
System.out.println("total memory:" + Runtime.getRuntime().totalMemory());
运行参数: -Xms5m -Xmx20m -XX:+PrintGCDetails -XX:+UseSerialGC -XX:+PrintCommandLineFlags
在实际工作中,可以直接讲初始化的堆大小与最大堆大小设置相等,这样的好处是可以减少运行时的垃圾回收次数,从而提高性能。
新生代的配置
-Xmn:可以设置新生代的大小,设置一个比较大的新生代会减少老年代的大小,这个参数堆系统的性能以及GC行为有较大的影响,新生代大小一般会设置整个堆空间的的1/3到1/4左右。
-XX:SurvivorRatio 用来设置新生代中eden空间和from/to空间的比例。(-XX:SurvivorRatio=eden/from=eden/to)
-XX:NewRatio 用来设置老年代和新生代的比例。(-XX:NewRatio=老年代/新生代)
byte[] b = null;
//连续向系统申请10MB空间
for(int i = 0 ; i <10; i ++){
b = new byte[1*1024*1024];
}
根据不同的参数运行:
-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
-Xms20m -Xmx20m -Xmn1m -XX:SurvivorRatio=6 -XX:+PrintGCDetails -XX:+UseSerialGC
-Xms20m -Xmx20m -Xmn7m -XX:SurvivorRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
-Xms20m -Xmx20m -XX:NewRatio=2 -XX:+PrintGCDetails -XX:+UseSerialGC
在java程序运行过程中,如果堆空间不足,则会抛出内存溢出错误(Out of Menory),一旦这类问题发生在生产环境,可能引起严重的业务中断,java虚拟机提供了 -XX:+HeapDumpOnOutOfMemoryError,使用该参数可以在内存溢出时导出整个堆信息,与之配合使用的参数有 -XX:HeapDumpPath ,可以设置导出堆的存放路径。
Vector v = new Vector();
for(int i=0; i < 5; i ++){
v.add(new Byte[1*1024*1024]);
}
-Xms1m -Xmx1m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=d:/Test03.dump
D盘生成 Test03.dump 文件,可能用 Memory Analyzer 工具分析。
java虚拟机提供了参数-Xss来指定线程最大的栈空间大小,整个参数也直接指定了函数可调用的最大深度。
//栈调用深度
rivate 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();
}
}
-Xss1m
-Xss5m