本文来自: HeapDump性能社区
概述
如今JDK8成了主流,大家都紧锣密鼓地进行着升级,享受着JDK8带来的各种便利,然而有时候升级并没有那么顺利?比如说今天要说的这个问题。我们都知道JDK8在内存模型上最大的改变是,放弃了Perm,迎来了Metaspace的时代。如果你对Metaspace还不熟,之前我写过一篇介绍Metaspace的文章,大家有兴趣的可以看看我前面的那篇文章。
我们之前一般在系统的JVM参数上都加了类似-XX:PermSize=256M -XX:MaxPermSize=256M的参数,升级到JDK8之后,因为Perm已经没了,如果还有这些参数JVM会抛出一些警告信息,于是我们会将参数进行升级,比如直接将PermSize改成MetaspaceSize,MaxPermSize改成MaxMetaspaceSize,但是我们后面会发现一个问题,经常会看到Metaspace的OutOfMemory异常或者GC日志里提示Metaspace导致的Full GC,此时我们不得不将MaxMetaspaceSize以及MetaspaceSize调大到512M或者更大,幸运的话,发现问题解决了,后面没再出现OOM,但是有时候也会很不幸,仍然会出现OOM。此时大家是不是非常疑惑了,代码完全没有变化,但是加载类貌似需要更多的内存?
之前我其实并没有仔细去想这个问题,碰到这类OOM的问题,都觉得主要是Metaspace内存碎片的问题,因为之前帮人解决过类似的问题,他们构建了成千上万

本文探讨了JDK8中由于重复类定义导致的内存泄漏问题。在JDK8的Metaspace中,由于缺少压缩操作,重复定义的类无法正常回收,可能导致OutofMemoryError。与JDK7的PermGen相比,Metaspace在类卸载上有显著差异,这使得某些情况下,即使类加载器存活,重复定义的类也无法释放,除非类加载器死亡。
最低0.47元/天 解锁文章
2876

被折叠的 条评论
为什么被折叠?



