Java PermGen会泄漏到本机堆中吗?

Java PermGen会泄漏到本机堆中吗?,java,memory-leaks,glassfish,jdk1.6,Java,Memory Leaks,Glassfish,Jdk1.6,我们正在运行具有以下设置的Glassfish应用程序: -XX:PermSize=1g -XX:MaxPermSize=2g -Xms4g -Xmx4g -XX:MaxDirectMemorySize=1048576 JDK版本是6u45 我们观察到内存泄漏-Glassfish的java进程不断增长-RES获得>15GB的内存(我们的服务器有16GB的物理内存,因此管理员在达到物理限制之前重新启动Glassfish),但我们从未获得java.lang.OutOfMemoryError 让应用程

我们正在运行具有以下设置的Glassfish应用程序:

-XX:PermSize=1g
-XX:MaxPermSize=2g
-Xms4g
-Xmx4g
-XX:MaxDirectMemorySize=1048576
JDK版本是6u45

我们观察到内存泄漏-Glassfish的java进程不断增长-
RES
获得>15GB的内存(我们的服务器有16GB的物理内存,因此管理员在达到物理限制之前重新启动Glassfish),但我们从未获得
java.lang.OutOfMemoryError

让应用程序长时间运行后,
jmap-permstat
的输出,显示类加载器占用了~9.5GB(!!!)

class_loader    classes bytes   parent_loader   alive?  type

<bootstrap> 4242    24064120      null      live    <internal>
0x0000000794a4c030  20  274072  0x0000000794a4c098  dead    groovy/lang/GroovyClassLoader$InnerLoader@0x0000000609cdc9f0
...
<many, many Groovy class loaders>
0x000000077f9c80d8  0   0   0x00000007017859f8  dead    groovy/lang/GroovyClassLoader@0x0000000609997f00
0x000000076d63b3e0  0   0   0x00000007017859f8  dead    groovy/lang/GroovyClassLoader@0x0000000609997f00
0x000000075a4c5248  20  261784  0x000000075a4c52b0  dead    groovy/lang/GroovyClassLoader$InnerLoader@0x0000000609cdc9f0
0x000000078ea2e998  0   0   0x00000007017859f8  dead    groovy/lang/GroovyClassLoader@0x0000000609997f00
...
total = 73518   745295  9690318280      N/A     alive=1, dead=73517     N/A    
我一直认为,使用
-XX:MaxPermSize
-Xmx
可以控制java进程将分配多少内存(如果需要更多内存,则抛出OOM)。 据我了解,这一过程大约需要:

4G (heap) + 2G (PermGen) + N*1MB (N thread's stacks) ~= 7.5G (by 500 threads)
问题 我们知道泄漏源于旧的Groovy版本和缺少PermGen扫描标志,但是类加载器怎么可能占用既不属于PermGen也不属于java堆的9.5GB内存


编辑
只是澄清一下-问题不在于如何解决内存泄漏问题,而是JVM如何允许这样的内存分配。不过,这不是一个很好的答案。 这很棘手。请注意,JVM将为
垃圾收集
(特别是G1)、元空间:Java8中的Permgen(因此不适用于您的情况)、JIT优化使用额外的回旋空间,这些空间可能位于正常垃圾收集堆之外

在任何一种情况下,都要分析堆转储以查看应用程序的行为。通常情况下,应用程序中的bug比JVM中的要多。另外,您应该让应用程序运行到
OutOfMemory
中,并查看提到的确切原因。

关于直接缓冲区(我们在代码中不使用它们),我使用了
-XX:MaxDirectMemorySize=1048576
来确保第三方LIB没有占用本机内存块。
4G (heap) + 2G (PermGen) + N*1MB (N thread's stacks) ~= 7.5G (by 500 threads)