/**
* JDK1.8/JDK1.6
*
* 虚拟机机栈和本地方法栈OOM测试(减小栈内存,模拟StackOverflowError)
*
* VM Args: -Xss128k
*
* @author 106.55.152.92:30989
* @date 2019年4月23日
*/
public class JavaVMStackSOF {
private int stackLength = 1;
public void stackLeak() {
stackLength++;
stackLeak();
}
public static void main(String[] args) throws Throwable {
JavaVMStackSOF oom = new JavaVMStackSOF();
try {
oom.stackLeak();
} catch (Throwable e) {
System.out.println("stack length: "+oom.stackLength);
throw e;
}
}
}
运行结果:
stack length:2402
Exception in thread "main" java.lang.StackOverflowError
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:20)
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:21)
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:21)
……后续异常堆栈信息省略
stack length:5675
Exception in thread "main" java.lang.StackOverflowError
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:27)
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28)
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28)
……后续异常堆栈信息省略
stack length:3716
java.lang.OutOfMemoryError
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:27)
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28)
at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28)
……后续异常堆栈信息省略
/**
* JDK1.6
*
* 运行时常量池导致的内存溢出异常(JDK1.8之后去除了方法区, 常量池移入堆内存,因此本实验只能在JDK1.6上测试)
*
* VM Args: -XX:PermSize=10M -XX:MaxPermSize=10M
*
* @author 106.55.152.92:30989
* @date 2019年4月23日
*/
public class RuntimeConstantPoolOOM {
public static void main(String[] args) {
//使用List保持着常量池的引用,避免Full GC回收常量池行为
List<String> list = new ArrayList<String>();
//10M的PermSize在integer范围内足够产生OOM了
int i = 0;
while(true) {
list.add(String.valueOf(i++).intern());
}
}
}
运行结果:
Exception in thread "main" java.lang.OutOfMemoryError: PermGen space
at java.lang.String.intern(Native Method)
at org.fenixsoft.oom.RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java: 18)
// OOM异常一:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.lang.Integer.toString(Integer.java:440)
at java.base/java.lang.String.valueOf(String.java:3058)
at RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java:12)
// OOM异常二:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.HashMap.resize(HashMap.java:699)
at java.base/java.util.HashMap.putVal(HashMap.java:658)
at java.base/java.util.HashMap.put(HashMap.java:607)
at java.base/java.util.HashSet.add(HashSet.java:220)
at RuntimeConstantPoolOOM.main(RuntimeConstantPoolOOM.java from InputFile-Object:14)
关于这个字符串常量池的实现在哪里出现问题, 还可以引申出一些更有意思的影响:
/**
*
* JDK1.8(true,false)/JDK1.6(false,false)
*
* JDK1.8移除方法区,常量池加入到堆内存,所以new对象的地址和intern()返回的常量池中的地址是相同的(详情见《JVM虚拟机P57》)
*
* String.intern()返回引用测试
*
* @author 106.55.152.92:30989
* @author 2019年4月23日
*
*/
public class RuntimeConstantPoolOOM2 {
public static void main(String[] args) {
String str1 = new StringBuilder("计算机").append("软件").toString();
System.out.println(str1.intern() == str1);
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern() == str2);
}
}
Caused by: java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
... 8 more
import javassist.CtClass;
/**
* Create by xuzhijun.online on 2019/5/7.
*/
public class MetaspaceOOM {
/**
* JVM参数:-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
*/
static javassist.ClassPool cp = javassist.ClassPool.getDefault();
public static void main(String[] args) throws Exception{
for (int i = 0; ; i++) {
CtClass c = cp.makeClass("com.xzj.TreeNode" + i);
if (c.isFrozen()){
c.defrost();
}
Class cc = c.toClass();
System.out.println(cc +" " +i);
}
}
}
测试结果:
D:\app\jdk1.8.0_251\bin\java.exe 报Compressed class space OOM
class com.xzj.TreeNode3078 3078
Exception in thread "main" javassist.CannotCompileException: by java.lang.OutOfMemoryError: Compressed class space
at javassist.ClassPool.toClass(ClassPool.java:1085)
at javassist.ClassPool.toClass(ClassPool.java:1028)
at javassist.ClassPool.toClass(ClassPool.java:986)
at javassist.CtClass.toClass(CtClass.java:1079)
at com.xzj.MetaspaceOOM.main(MetaspaceOOM.java:28)
Caused by: java.lang.OutOfMemoryError: Compressed class space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.lang.ClassLoader.defineClass(ClassLoader.java:635)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javassist.ClassPool.toClass2(ClassPool.java:1098)
at javassist.ClassPool.toClass(ClassPool.java:1079)
... 4 more
class com.xzj.TreeNode5681 5681
Exception in thread "main" javassist.CannotCompileException: by java.lang.OutOfMemoryError: Metaspace
at javassist.ClassPool.toClass(ClassPool.java:1085)
at javassist.ClassPool.toClass(ClassPool.java:1028)
at javassist.ClassPool.toClass(ClassPool.java:986)
at javassist.CtClass.toClass(CtClass.java:1079)
at com.xzj.MetaspaceOOM.main(MetaspaceOOM.java:20)
Caused by: java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at javassist.ClassPool.toClass2(ClassPool.java:1098)
at javassist.ClassPool.toClass(ClassPool.java:1079)
... 4 more