Java8元空间&;堆使用
我有这个代码来动态生成类并加载它Java8元空间&;堆使用,java,jvm,java-8,jvm-hotspot,metaspace,Java,Jvm,Java 8,Jvm Hotspot,Metaspace,我有这个代码来动态生成类并加载它 import javassist.CannotCompileException; import javassist.ClassPool; public class PermGenLeak { private static final String PACKAGE_NAME = "com.jigarjoshi.permgenleak."; public static void main(String[] args) throws CannotC
import javassist.CannotCompileException;
import javassist.ClassPool;
public class PermGenLeak {
private static final String PACKAGE_NAME = "com.jigarjoshi.permgenleak.";
public static void main(String[] args) throws CannotCompileException, InterruptedException {
for (int i = 0; i < Integer.MAX_VALUE; i++) {
ClassPool pool = ClassPool.getDefault();
pool.makeClass(PACKAGE_NAME + i).toClass();
Thread.sleep(3);
}
}
}
import javassist.CannotCompileException;
导入javassist.ClassPool;
公共类永久泄漏{
私有静态最终字符串包\u NAME=“com.jigarjoshi.permgenleak。”;
公共静态void main(字符串[]args)抛出CannotCompileException、InterruptedException{
对于(int i=0;i
我针对Java7(jdk1.7.0_60)启动了这个类,正如预期的那样,它填满了PermGenSpace,堆仍然没有使用
图中显示了permgen使用超时以及JVM终止时的情况
现在,同样的代码运行在Java 8(jdk1.8.0_40-ea)上,正如预期的那样,它不断扩展本机内存(元空间),但令人惊讶的是,对于1g的元空间,它在OldGen中消耗了3g的堆(随着时间的推移,几乎维持了3倍的元空间)
此图显示元空间使用超时和系统内存使用示例
说
internedString
和类统计信息以及一些杂项数据已移动到堆中
当堆将更多类加载到元空间时,究竟是什么导致堆的增加
当堆将更多类加载到元空间时,究竟是什么导致堆的增加
我的假设是,这是你的例子所创造的“普通”垃圾。我猜想:
代码创建常规堆对象。它们大多是“大”的,这导致它们被直接分配到OldGen堆中。或者是其他原因造成的 (更新-看看@apangin的答案,我现在怀疑他们是从YoungGen堆开始的,并且是终身制的…)javaassist
- 在后台调用
时,它会从包含类文件的字节数组中创建元空间中的对象classLoader.defineClass
- 旧用法仍然是。。。因为还没有触发完整的GC
如果您调整示例使类可以访问,然后强制执行完整的GC,我希望看到旧堆使用率下降,这表明它是“普通”垃圾,而不是存储泄漏。运行
jmap-histo-PID
查看哪些对象占用堆空间。当我运行您的示例时,我看到堆中充满了Javassist辅助对象:
num #instances #bytes class name
----------------------------------------------
1: 592309 312739152 [Ljavassist.bytecode.ConstInfo;
2: 6515673 208501536 java.util.HashMap$Node
3: 2964403 169188824 [C
4: 1777622 102165184 [Ljava.lang.Object;
5: 4146200 99508800 javassist.bytecode.Utf8Info
6: 3553889 85293336 java.util.ArrayList
7: 2964371 71144904 java.lang.String
8: 593075 56944008 java.lang.Class
9: 592332 47388032 [Ljava.util.HashMap$Node;
10: 592309 37907776 javassist.bytecode.ClassFile
11: 592308 37907712 javassist.CtNewClass
12: 1185118 28555808 [B
13: 592342 28432416 java.util.HashMap
14: 1184624 28430976 javassist.bytecode.ClassInfo
15: 592309 28430832 [[Ljavassist.bytecode.ConstInfo;
16: 592322 23692880 javassist.bytecode.MethodInfo
17: 592315 23692600 javassist.bytecode.CodeAttribute
18: 592434 18957888 java.util.Hashtable$Entry
19: 592309 18953888 javassist.bytecode.ConstPool
20: 592308 18953856 java.lang.ref.WeakReference
21: 592318 14215632 javassist.bytecode.MethodrefInfo
22: 592318 14215632 javassist.bytecode.NameAndTypeInfo
23: 592315 14215560 javassist.bytecode.ExceptionTable
24: 592309 14215416 javassist.bytecode.LongVector
25: 592309 14215416 javassist.bytecode.SourceFileAttribute
26: 592507 9487584 [I
27: 8 6292528 [Ljava.util.Hashtable$Entry;
28: 212 18656 java.lang.reflect.Method
29: 407 13024 java.util.concurrent.ConcurrentHashMap$Node
30: 124 8928 java.lang.reflect.Field
谢谢Stephen,现在这完全有道理了,我想我在Java 7示例中没有达到这个分配比例,这就是为什么我在Java 7中没有看到它,你能提供代码来演示你的解决方案吗谢谢Andrei,我应该执行这个,我想我在Java 7示例中没有达到这个比例,这就是为什么我在Java 7中没有看到它