常见JVM错误代码示例
一、常见JVM异常示例代码:
package com.houxr.jvm.study;
import com.google.common.collect.Lists;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* jvm test
* 需要设置 VM options : -Xms1m -Xmx1m -XX:MaxMetaspaceSize=5M
* https://blog.csdn.net/soonfly/article/details/70147205
* @author houxiurong
* @date 2018-11-01
*/
public class JvmTest extends ClassLoader {
/**
* List是动态增长的,因此容量不够了,就会扩容,一旦空闲内存分配完毕,请求不到其他内存,就抛出OutOfMemoryError。
* <p>
* 模拟OutOfMemoryError 堆溢出错误
* java.lang.OutOfMemoryError: Java heap space
*/
public static void outOfMemoryError() {
ArrayList list = Lists.newArrayList();
while (true) {
list.add(new JvmTest());
}
}
/**
* 不断往堆中塞新增的StringBuffer对象,堆满了就直接溢出了
* Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
*/
public static void heapOverFlow() {
int count = 10000;
int size = 0;
while (true) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < count; i++) {
buffer.append(i);
}
System.out.println("=======================" + (++size));
}
}
/**
* 栈溢出错误
* 程序详解:
* 执行main函数会创建一个线程,同时创建一个虚拟机栈(栈内存)
* 调用JvmTest.stackOverflowError()时,会对 stackOverflowError()进行压栈操作,将 stackOverflowError()运行期数据的数据集
* 保存到栈帧(Stack Frame)(如果main方法里面调用多个方法,会执行多个压栈操作)。
* stackOverflowError()递归调用时,都会产生一个新的栈帧区块,这时就会连续的产生新的栈帧区块
* 当栈内存超过系统配置的栈内存-Xss:2048,就会出现java.lang.StackOverflowError异常.这也是为什么对于需要谨慎使用递归调用的原因!
* Stack length:11131
* <p>
* Exception in thread "main" java.lang.StackOverflowError
*/
public void stackOverflowError() {
STACK_COUNT++;
stackOverflowError();
}
private Integer STACK_COUNT = 1;
/***
* 运行时常量池导致内存溢出
* JDK1.7 Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
* JDK1.8 CMS Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
*/
public static void runtimeConstantPoolOOM1() {
//List保持常量池引用,避免Full GC回收常量池行为
List<String> list = Lists.newArrayList();
int i = 0;
while (true) {
list.add(String.valueOf(i++).intern());
}
}
/**
* 运行时常量溢出-问题思考
* String.intern()是一个Native方法,
* 作用是:如果字符串常量池中已经包含一个等于此String对象的字符串,
* 则返回代表池中这个字符串的String对象,否则,将此String对象包含的字符串添加到常量池中,并且返回此String对象的引用。
*/
public static void runtimeConstantPoolOOM2() {
String str1 = new StringBuilder("土豆丝").append("不加辣").toString();
String str11 = "土豆丝不加辣";
//JDK 1.6 false JDK 1.7 true JDK 1.8 false
System.out.println("========str1======" + (str1.intern() == str1));
// JDK 1.8 true
System.out.println("========str11======" + (str1.intern().equals(str11)));
String str2 = new StringBuilder("ja").append("va").toString();
String str22 = str2.intern();
//JDK 1.6 false JDK 1.7 true JDK 1.8 false
System.out.println("========str2======" + (str2 == str22));
}
/**
* 方法区溢出
* <p>
* MetaSpace 溢出
* 方法区的内存溢出 中, JDK8 没有了永久代的概念
* 在JDK8中,使用了MetaSpace的区域来存放Class的相关信息,
* 当 MetaSpace 内存空间不足时, 会抛出 java.lang.OutOfMemoryError: Metaspace异常.
* $ -XX:MaxMetaspaceSize=5M
* CGLIB直接操作字节码运行时,生成大量的动态类
*/
public static void jdk8MethodAreaOOM() {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(JvmTest.class);
enhancer.setUseCache(false);
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
return methodProxy.invokeSuper(o, objects);
}
});
enhancer.create();
}
}
public static void main(String[] args) throws Throwable {
// 模拟OutOfMemoryError 堆溢出错误
// JvmTest.outOfMemoryError();
// JvmTest.heapOverFlow();
//栈溢出
JvmTest jvmTest = new JvmTest();
try {
jvmTest.stackOverflowError();
} catch (Throwable e) {
System.out.println("========Stack length:" + jvmTest.STACK_COUNT);
throw e;
}
// 运行时常量池导致内存溢出
// JvmTest.runtimeConstantPoolOOM1();
// JvmTest.runtimeConstantPoolOOM2();
//jvm 8 永久代去掉使用 MetaSpace
// JvmTest.jdk8MethodAreaOOM();
}
}
二、调试上面代码最好在IDEA或者Eclipse中设置如下参数,会有更好的效果。
-Xms5m -Xmx5m -XX:MetaspaceSize=5m -XX:MaxMetaspaceSize=5M -Xss256k -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintClassHistogram -XX:+HeapDumpOnOutOfMemoryError
本文共计 7311 字,感谢您的耐心浏览与评论。
0条回应:“常见JVM错误代码示例”