-Xms: 堆的初始值,例如 -Xmx2048,初始堆大小为 2G
-Xmx: 堆的最大值,例如 -Xmx2048M,允许最大堆内存 2G
-Xmn: 新生代大小
-XX:SurvivorRatio:Eden 区所占比例,默认是 8,也就是 80%,例如 -XX:SurvivorRatio=8
-Xss:栈空间大小,栈是线程独占的,所以是一个线程使用栈空间的大小,例如 -Xss256K,如果不设置此参数,默认值是 1M,一般来讲设置成 256K 就足够了。
简单日志
-verbose:gc 或者 -XX:+PrintGC
#打印详细日志
-XX:+PrintGCDetails
#打印 GC 的时间点
-XX:+PrintGCDateStamps
GC 前后的堆信息
-XX:+PrintHeapAtGC
GC 导致的 Stop the world 时间
-XX:+PrintGCApplicationStoppedTime
加载类信息
-verbose:class
GC 前后的类加载情况
-XX:+PrintClassHistogramBeforeFullGC
-XX:+PrintClassHistogramAfterFullGC
日志输入到文件
#GC 活动日志,根据配置的参数输出内容
-Xloggc:/Users/fengzheng/jvmlog/gc.log
#致命错误日志,只有在 jvm 发生崩溃的时候会输出
-XX:ErrorFile=/Users/fengzheng/jvmlog/hs_err_pid%p.log
溢出现场保留
-XX:HeapDumpPath=/Users/fengzheng/jvmlog
-XX:+HeapDumpOnOutOfMemoryError
JDK 8 中可使用的垃圾收集器以及它们配合使用的关系。
Serial、ParNew、Parallel Scavenge 只适用于年轻代,CMS、Serial Old、Parallel Old 只适用于老年代,而 G1 通用于年轻代和老年代。连线表示它们之间可配合使用的关系,其中 CMS 和 Serial Old 连线的意思是说 Serial Old 会作为 CMS 的后预案,当 CMS 发生 Concurrent Mode Failure 时启用。
在 JDK 8 中,如果不指定垃圾收集器,默认使用参数 -XX:+UseParallelGC,新生代使用 Parallel Scavenge,老年代使用 Serial Old。
-XX:+UseSerialGC:使用 Serial + Serial Old ,运行于 client 模式下的默认设置
-XX:+UseConcMarkSweepGC:使用 ParNew+CMS+Serial Old,CMS 垃圾收集器
-XX:+UseParallelGC:Parallel Scavenge + Serial Old,JDK 8 server 模式下的默认设置
-XX:+UseParallelOldGC:Parallel Scavenge + Parallel Old
-XX:+UseG1GC:使用 G1 垃圾收集器
开启远程 JMX 监控
除了日志外,当我们需要实时查看 JVM 运行情况的时候怎么办,当然可以到 JVM 所在服务器用 jstack、jmap、jinfo 等工具进行查看,但是又不够直观,这时候就需要开启 JMX 远程功能,使用 jConsole、VisualVM 等工具进行监控。或者自己开发监控平台
开启参数如下:
-Dcom.sun.management.jmxremote
#指定 jvm 所在服务器 ip 或域名
-Djava.rmi.server.hostname=192.168.1.1
#指定端口
-Dcom.sun.management.jmxremote.port=9999
-Dcom.sun.management.jmxremote.rmi.port=9999
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false
堆溢出(-Xms20M -Xmx20M)
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
public void outOfMemory(){
List<Integer> list = new ArrayList<>();
while(true){
list.add(1);
}
}
栈溢出(-Xss128k)
递归超出栈的深度
private int i ;
public void plus() {
i++;
plus();
}
常量池溢出(-XX:PermSize=10M -XX:MaxPermSize=10M
try {
List<String> strings = new ArrayList<String>();
int i = 0;
while(true){
strings.add(String.valueOf(i++).intern());
}
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
方法去溢出
-XX:PermSize=10M -XX:MaxPermSize=10M
while(true){
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TestCase.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
return arg3.invokeSuper(arg0, arg2);
}
});
enhancer.create();
}
直接内存溢出
-Xmx20M -XX:MaxDirectMemorySize=10M
Field field = Unsafe.class.getDeclaredField("theUnsafe");
field.setAccessible(true);
Unsafe unsafe = (Unsafe) field.get(null);
while (true) {
unsafe.allocateMemory(ONE_MB);
count++;
}