0%

java | 方法区

Method Area 方法区。

方法区在 1.61.8 的实现是不同的。

1.8 之后,方法区就放在内存中了。而,1.6 方法区是放在 jvm 内存中的。

内存溢出

  • 1.8 之前会导致永久代内存溢出
  • 1.8 之后会导致元空间内存溢出

VM 参数设置元空间大小 -XX:MaxMetaspaceSize=20m。运行下面代码钱,设置元空间大小为 20m

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.redisc;

import jdk.internal.org.objectweb.asm.ClassWriter;
import jdk.internal.org.objectweb.asm.Opcodes;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
* 元空间内存溢出
* -XX:MaxMetaspaceSize=8m
* */

@Slf4j(topic = "c.Run")
public class Run extends ClassLoader { // ClassLoader 用来加载类的二进制字节码

public static void main(String[] args) throws Exception {
int j = 0;
try {
Run run = new Run();
for (int i = 0; i < 100000; 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();
//执行了类的加载
run.defineClass("Class" + i, code, 0, code.length);
}
} finally {
System.out.println(j);
}
}

}

输出

1
2
3
4
5
6
23816
Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:757)
at java.lang.ClassLoader.defineClass(ClassLoader.java:636)
at com.redisc.Run.main(Run.java:29)
请我喝杯咖啡吧~