跟踪调试参数
-XX:PrintGC //最简单的GC日志
-XX:PrintGCDetails //输出GC详细信息
-XX:+PrintHeapAtGC //在每次GC前后打印详细信息,如同
//—XX:PrintGCDetails最后输出一样
-XX:+PrintGCTimeStamps //额外输出GC时间:虚拟机启动后的时间偏移量
-XX:+PrintGCApplicationConcurrentTime //应用程序的执行时间
-XX:+PrintGCApplicationStoppedTime //应用程序由于GC的停顿时间
-XX:+PrintReferenceGC //跟踪GC时引用信息
-Xloggc:log/gc.log //将GC日志输出到当前目录log文件夹下
//的gc.log文件中
-verbose:class //跟踪类的加载与卸载
-XX:TraceClassLoading //跟踪类的加载
-XX:TraceClassUnloading //跟踪类的卸载
-XX:+PrintVMOptions //打印虚拟机接受的显式命令行参数
-XX:+PrintCommandLineFlags //打印虚拟机接受的显式和隐式命令行参数
-XX:+PrintFlagsFinal //打印虚拟机所有参数的值
堆参数设置
- 最大堆和初始堆
通过下面示例分析堆参数设置:
public class SimpleArgs {
public static void main(String[] args) {
System.out.print("maxMemory=");
System.out.println(Runtime.getRuntime().maxMemory()+" bytes");
System.out.print("freeMemory=");
System.out.println(Runtime.getRuntime().freeMemory()+" bytes");
System.out.print("totalMemory=");
System.out.println(Runtime.getRuntime().totalMemory()+" bytes");
byte[] bytes=new byte[1024*1024];
System.out.println("分配了1M空间给数组");
System.out.print("maxMemory=");
System.out.println(Runtime.getRuntime().maxMemory()+" bytes");
System.out.print("freeMemory=");
System.out.println(Runtime.getRuntime().freeMemory()+" bytes");
System.out.print("totalMemory=");
System.out.println(Runtime.getRuntime().totalMemory()+" bytes");
bytes=new byte[1024*1024*4];
System.out.println("分配了4M空间给数组");
System.out.print("maxMemory=");
System.out.println(Runtime.getRuntime().maxMemory()+" bytes");
System.out.print("freeMemory=");
System.out.println(Runtime.getRuntime().freeMemory()+" bytes");
System.out.print("totalMemory=");
System.out.println(Runtime.getRuntime().totalMemory()+" bytes");
}
}
编译成.class文件后,在Windows下找到class文件目录,shift+右键->在此处打开命令窗口,然后执行下面指令:
java -Xmx20m -Xms5m -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseSerialGC SimpleArgs
-XX:InitialHeapSize=5242880 -XX:MaxHeapSize=20971520 -XX:+PrintCommandLineFlags -XX:+PrintGCDetails -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:-UseLargePagesIndividualAllocation -XX:+UseSerialGC
maxMemory=20316160 bytes
freeMemory=5072200 bytes
totalMemory=6094848 bytes
[GC (Allocation Failure) [DefNew: 1032K->192K(1856K), 0.0021823 secs] 1032K->660K(5952K), 0.0040585 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
分配了1M空间给数组
maxMemory=20316160 bytes
freeMemory=4337784 bytes
totalMemory=6094848 bytes
[GC (Allocation Failure) [DefNew: 1247K->0K(1856K), 0.0020978 secs][Tenured: 1684K->1684K(4096K), 0.0021361 secs] 1715K->1684K(5952K), [Metaspace: 2698K->2698K(1056768K)], 0.0045926 secs] [Times: user=0.00 sys=0.00, real=0.00 secs]
分配了4M空间给数组
maxMemory=20316160 bytes
freeMemory=4405888 bytes
totalMemory=10358784 bytes
Heap
def new generation total 1920K, used 50K [0x00000000fec00000, 0x00000000fee10000, 0x00000000ff2a0000)
eden space 1728K, 2% used [0x00000000fec00000, 0x00000000fec0caf8, 0x00000000fedb0000)
from space 192K, 0% used [0x00000000fedb0000, 0x00000000fedb0000, 0x00000000fede0000)
to space 192K, 0% used [0x00000000fede0000, 0x00000000fede0000, 0x00000000fee10000)
tenured generation total 8196K, used 5780K [0x00000000ff2a0000, 0x00000000ffaa1000, 0x0000000100000000)
the space 8196K, 70% used [0x00000000ff2a0000, 0x00000000ff845118, 0x00000000ff845200, 0x00000000ffaa1000)
Metaspace used 2705K, capacity 4486K, committed 4864K, reserved 1056768K
class space used 302K, capacity 386K, committed 512K, reserved 1048576K
设置最大内存为20MB,最小为5MB,从log中当前最大的内存由-XX:MaxHeapSize=20971520(=20*1024*1024)指定。
而打印的最大可用内存(maxMemory=20316160 bytes)要比20971520略小。这是由于新生代的复制算法导致的from/to空间大小的浪费。从信息中可以看到from大小为 0x00000000fede0000-0x00000000fedb0000=0x20000=131072 byes,但是20971520 -131072=20840448>20316160 ,这是由于虚拟机并没有直接使用from/to的大小,而是进一步做了对其操作。
- 新生代设置
-Xmn //设置新生代绝对大小 :eden+from+to
-XX:SurvivorRatio //设置eden区和from/to区的比例
-XX:NewRatio //老年代/新生代
来自《实战Java虚拟机》
栈溢出处理
-XX:+HeapDumpOnOutOfMemoryError //设置在内存溢出时,导出整个堆信息
-XX:HeapDumpPath=d:/save.dump //设置导出堆信息的存放路径
非堆区参数配置
- 方法区配置
在JDK1.6、JDK1.7
-XX:PermSize //设置永久区初始大小
-XX:MaxPermSize //设置最大永久区
在JDK1.8中永久区被移除,使用元数据区存放类的元数据
-XX:MaxMetaspaceSize //设置最大元数据区,,默认只受系统可用内存限制
- 栈配置
-Xss //指定线程的栈大小
- 直接内存设置
-XX:MaxDirectMemorySize //最大直接内存,默认为最大堆空间,击-Xmx
直接内存的访问要快于堆内存,但是在申请内存空间时堆空间的速度远远高于直接内存。
- 虚拟机工作模式
-server //收集更多系统性能信息,对程序进行优化,启动较慢
-client //Client启动速度较快
注意
- 堆内存和方法区属于不同的内存空间
- 常量池JDK1.6是放在方法区当中;在JDK1.7中的常量池移到了堆中;在JDK1.8中移除整个永久代,常量池又移到元数据区当中。