2.8方法区内存溢出
1.8以前会导致永久代内存溢出
测试代码如下,为了演示内存溢出,运行代码时添加虚拟机参数-XX:MaxPermSize=10m
package xx;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* 演示永久代内存溢出
* -XX:MaxPermSize=10m
*/
public class Demo1 extends ClassLoader { // 可以用来加载类的二进制字节码
public static void main(String[] args) {
int j = 0;
try {
Demo1 test = new Demo1();
for (int i = 0; i < 10000; i++, j++) {
// ClassWriter作用是生成类的二进制字节码
ClassWriter cw = new ClassWriter(0);
// 版本号,public,类名,包名,父类,接口
cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
// 返回byte[]
byte[] code = cw.toByteArray();
// 执行了类的加载
test.defineClass("Class" + i, code, 0, code.length);
}
} finally {
System.out.println(j);
}
}
}
如期所料内存溢出。报错信息为java.lang.OutOfMemoryError: PermGen space
F:\Java\jdk-1.6\bin\java.exe -XX:MaxMetaspaceSize=10m "-javaagent:F:\installation\JetBrains\IntelliJ IDEA
3435 # 运行3435次循环之后内存溢出
Exception in thread "main" java.lang.OutOfMemoryError: PermGen 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 xx.Demo1.main(Demo1.java:25)
Process finished with exit code 1
1.8以后会导致元空间内存溢出
测试代码如下,为了演示内存溢出,运行代码时添加虚拟机参数-XX:MaxMetaspaceSize=10m
package xx;
import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
/**
* 演示元空间内存溢出
* -XX:MaxMetaspaceSize=10m
*/
public class Demo1 extends ClassLoader { // 可以用来加载类的二进制字节码
public static void main(String[] args) {
int j = 0;
try {
Demo1 test = new Demo1();
for (int i = 0; i < 10000; i++, j++) {
// ClassWriter作用是生成类的二进制字节码
ClassWriter cw = new ClassWriter(0);
// 版本号,public,类名,包名,父类,接口
cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC, "Class" + i, null, "java/lang/Object", null);
// 返回byte[]
byte[] code = cw.toByteArray();
// 执行了类的加载
test.defineClass("Class" + i, code, 0, code.length);
}
} finally {
System.out.println(j);
}
}
}
如期所料内存溢出。报错信息为java.lang.OutOfMemoryError: Metaspace
F:\Java\jdk-1.8.0_231\bin\java.exe -XX:MaxMetaspaceSize=10m "-javaagent:F:\installation\JetBrains\IntelliJ IDEA
3331 # 运行3331次循环之后内存溢出
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)
at java.lang.ClassLoader.defineClass(ClassLoader.java:635)
at xx.Demo1.main(Demo1.java:25)
Process finished with exit code 1
动态产生类的场景
Spring
Mybatis
注意:Spring和Mybatis中都使用了cglib来动态生成类,cglib和ClassWriter作用相同,都是用来动态生成类
Last updated
Was this helpful?