我特别研究了你的代码ClassPool#makeClass
。我注意到有几点导致堆空间随着元空间的增加而增加。
- 它
cache
是由方法 makeClass 在哈希表中创建的类
受保护的哈希表类;
因此,对于万分之一的课程,它具有每个类别的条目。因此,堆空间也增加了,它不是 GC,因为您的 for 循环仍然使用哈希表引用并不断更新,因此不符合 gc 的条件。
CtNewClass
创建类的新实例,它的构造函数定义如下:
CtNewClass(String name, ClassPool cp, boolean isInterface, CtClass superclass) {
super(name, cp);
this.wasChanged = true;
String superName;
if (!isInterface && superclass != null) {
superName = superclass.getName();
} else {
superName = null;
}
this.classfile = new ClassFile(isInterface, name, superName);
if (isInterface && superclass != null) {
this.classfile.setInterfaces(new String[]{superclass.getName()});
}
this.setModifiers(Modifier.setPublic(this.getModifiers()));
this.hasConstructor = isInterface;
}
在上面的代码中,this.classfile = new ClassFile(isInterface, name, superName);
实际上为每个类创建了新的 ConstPool 实例,即为每个实例创建了新的 HashMap 实例,并且这些在堆空间上保留了内存。
HashMap 类;//来自 ConstPool 类
HashMap 字符串;//来自 ConstPool 类
此外,这会创建两个新的 ArrayList。在上面的构造函数中观察this.fields = new ArrayList();
和this.methods = new ArrayList();
声明。另外,一个新的链表this.attributes = new LinkedList();
。
因此,结论是 ClassPool 有它的缓存管理,它占用了大量的堆空间。然后每个类都有自己的集合来管理属性、常量等。
希望能帮助到你!