假设我使用以下参数启动我的Java VM:
-Xms1024m -Xmx1024m -XX:PermSize=512m -XX:MaxPermSize=512m
Run Code Online (Sandbox Code Playgroud)
512m PermGen空间是否会添加到1024m内存中,还是它们的一部分?或者换句话说,我的总内存消耗是1536米还是1024米?在后一种情况下,这是否意味着应用程序只有512m用于PermGen空间以外的目的?
如果这个问题显示对PermGen空间缺乏了解,请告诉我.;-)
最近,我写了一个类,在其中我发现我可以减少~10个字节/元素的内存消耗,但这只是以使代码更加复杂为代价.这使编译.class文件的大小增加了大约10KB.
我假设JVM必须将.class文件加载到内存中,因此除非至少有1000个元素,否则这些更改不会为自己付费.但是,除非类文件中额外的10KB是增加代码复杂性的唯一成本,否则该算法无法解决.
这个Oracle博客表明,permgen中的类消耗了相当多的额外内存,而不仅仅是基于.class文件 - 例如,我怀疑更复杂的代码可能需要更多的内存来优化元数据.
所以,这个问题有两个部分:
Dalvik VM的类似细节将不胜感激,但我主要关注的是OpenJDK和其他"主流"JVM.
给定堆转储或正在运行的VM,如何发现永久代的内容是什么?我知道'jmap -permstat'但是在Windows上不可用.
我正在努力解决最近出现的outOfMemory PermGen问题.出现错误时保存的其中一个日志片段:
java.lang.OutOfMemoryError: PermGen space
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.findClass(ModuleImpl.java:1872)
at org.apache.felix.framework.ModuleImpl.findClassOrResourceByDelegation(ModuleImpl.java:720)
at org.apache.felix.framework.ModuleImpl.access$300(ModuleImpl.java:73)
at org.apache.felix.framework.ModuleImpl$ModuleClassLoader.loadClass(ModuleImpl.java:1733)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
Run Code Online (Sandbox Code Playgroud)
我增加了最大烫发大小,-XX:MaxPermGen=128m但这只是一个临时解决方案,因为我很确定我们在这里面临一些内存泄漏.我们的应用程序的Web部分部署在jetty(jsf + icefaces)上.单击随机组件会增加使用的内存 - 我正在监视它,jstat -gcold几乎每次命中都会增加3-4kb.我已经添加-XX:+TraceClassLoading到jvm params并且看到很多sun.reflect.GeneratedConstructorAccessor并且sun.reflect.GeneratedMethodAccessor在Web用户界面上有任何操作时被记录.当使用99%的permgen时,我也进行了堆转储.我使用YourKit分析器来分析堆.在类加载器选项卡中,有一些sun.reflect.DelegatingClassLoader行,每个行有1个类.什么可能导致记忆不断增长?任何帮助将非常感激.
提前谢谢,卢卡斯
我是Cojure的新手,但我读到在使用AOT编译时会为每个函数生成一个类.这是不是意味着很多消耗了perm-gen空间的类?这有什么问题吗?什么时候不使用AOT编译,但是动态生成字节码?
我正在Jenkins构建服务器上构建Maven Java应用程序.我java.lang.OutOfMemoryError: PermGen space在Jenkins构建期间遇到了很多次(但从未在我的localhost上),因此它无法构建.
我已经尝试过设置MAVEN_OPTSJenkins:我进入了Jenkins- > Manage Jenkins- > Configure system- > Global MAVEN_OPTS并且设置为-Xms512m -Xmx1024m -XX:MaxPermSize=512m -XX:PermSize=512m.尽管将其设置为这个高价值,我们仍然会遇到PermGen空间问题.我不想将MAVEN_OPTS设置为更高的值; 我不知道我的应用程序如何需要一个空间,我宁愿深入研究高内存使用问题.
最近,我一直在想,也许permgen空间问题不是来自Maven本身,而是来自Maven旋转的JVM进程之一(例如:插件).我提出这个假设,因为Maven仍然能够执行TestNG测试,尽管已经吐出了我们的permgen空间错误线.导致PermGen错误的一个这样的插件是Jetty:
Oct 31, 2012 7:55:37 AM com.google.apphosting.utils.jetty.JettyLogger warn
WARNING: handle failed
java.lang.OutOfMemoryError: PermGen space
Run Code Online (Sandbox Code Playgroud)
因此,我想知道:
该MAVEN_OPTS变量是否也适用于Maven构建旋转的子JVM进程?如果没有,那么如何为这些子进程(如Jetty)设置JVM选项?
注意:我使用的是Maven 3.0.4.
我在Glassfish上部署了一个应用程序.随着时间的推移,加载的班级数量攀升至数百万,而我的permgen似乎也在增加.
为了帮助排除故障,我将以下内容添加到我的jvm参数中.-XX:+ PrintGCDetails -XX:+ TraceClassUnloading -XX:+ TraceClassLoading
现在,在观看输出时,我看到一遍又一遍地加载相同的类.基本上每次调用Web服务时都会使用JAXB来处理xml.
[从JVM_DefineClass加载com.strikeiron.ZIPCodesInRadius $ JaxbAccessorF_userID ] [ 从JVM_DefineClass加载com.strikeiron.ZIPCodesInRadius $ JaxbAccessorF_userID ]
这是否表示泄漏?如果是,我该如何解决?
我们已经让我们的glassfish实例每两周下降一段时间java.lang.OutOfMemoryError: PermGen space.我将PermGen空间增加到512MB,并将startet转储内存使用量jstat -gc.两周后,我想出了下图,显示了PermGen空间是如何稳定增加的(x轴上的单位是分钟,y轴是KB).

我试着用谷歌搜索某种可以查明错误的分析工具,并在SO上提到一个线程提到jmap,这被证明是非常有帮助的.在倾倒的大约14000行中jmap -permstats $PID,大约包含12500行groovy/lang/GroovyClassLoader$InnerLoader,指向我们自己的Groovy代码或Groovy本身的某种内存泄漏.我必须指出,Groovy构造的相关代码库不到1%.
示例输出如下:
class_loader classes bytes parent_loader alive? type
<bootstrap> 3811 14830264 null live <internal>
0x00007f3aa7e19d20 20 164168 0x00007f3a9607f010 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00007f3a7afb4120
0x00007f3aa7c850d0 20 164168 0x00007f3a9607f010 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00007f3a7afb4120
0x00007f3aa5d15128 21 181072 0x00007f3a9607f010 dead groovy/lang/GroovyClassLoader$InnerLoader@0x00007f3a7afb4120
0x00007f3aad0b40e8 36 189816 0x00007f3a9d31fbf8 dead org/apache/jasper/servlet/JasperLoader@0x00007f3a7d0caf00
....
Run Code Online (Sandbox Code Playgroud)
那么我该如何进一步了解导致此问题的代码呢?
在本文中,我推断我们的Groovy代码是在某处动态创建类.从jmap的转储我可以看到大多数死对象/类(?)都有相同的parent_loader,虽然我不确定这在这个上下文中意味着什么.我不知道怎么从这里开始.
对于后来者来说,值得指出的是,接受的答案并不能解决问题.它只是通过不存储如此多的类信息来延长重启前所需的时间十倍.实际修复我们问题的是摆脱生成它的代码.我们使用验证(按合同设计)框架OVal,其中可以使用Groovy编写自定义约束作为方法和类的注释.在普通Java中删除注释以支持显式的前置条件和后置条件是很无聊的,但它完成了工作.我怀疑每次检查OVal约束时都会创建一个新的匿名类,并且关联的类数据以某种方式导致内存泄漏.
有谁知道为什么java 7无法收集永久代的app,导致java.lang.OutOfMemoryError:PermGen,而java 5收集永久代和app运行良好?
App在循环中对jython表达式进行评估,一次迭代约为.5秒 循环体看起来像:
PythonInterpreter py = new PythonInterpreter();
py.set("AI", 1);
((PyInteger)py.eval(expr)).getValue()
Run Code Online (Sandbox Code Playgroud)
用于在java 7和java 5中运行的app的jvisual vm的屏幕截图.
在这两种情况下都使用相同的参数:
-Xmx700m
-XX:MaxPermSize=100m
-XX:+HeapDumpOnOutOfMemoryError
-Xloggc:"C:\Temp\gc.log" -XX:+PrintGCDetails -XX:-TraceClassUnloading -XX:+PrintClassHistogram
Run Code Online (Sandbox Code Playgroud)

对stop或undeploy/redeploy一的Spring framework 3.0.5基于Web的应用程序中记录以下错误Tomcat7's catalina.out:
SEVERE: The web application [/nomination##1.0-qa] created a ThreadLocal with key of type [java.lang.ThreadLocal] (value [java.lang.ThreadLocal@4f43af8f]) and a value of type [org.springframework.security.core.context.SecurityContextImpl] (value [org.springframework.security.core.context.SecurityContextImpl@ffffffff: Null authentication]) but failed to remove it when the web application was stopped. Threads are going to be renewed over time to try and avoid a probable memory leak.
Run Code Online (Sandbox Code Playgroud)
我最初想到实现ServletContextListener和close()那里的背景.但是,发现ContextLoaderListener哪个工具ServletContextListener设置如下web.xml:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Run Code Online (Sandbox Code Playgroud)
来自Javadocs:
**contextDestroyed** …Run Code Online (Sandbox Code Playgroud) memory-leaks spring-mvc permgen servlet-listeners servletcontextlistener
permgen ×10
java ×8
memory-leaks ×4
memory ×2
classloader ×1
clojure ×1
icefaces ×1
jenkins ×1
jmap ×1
jsf ×1
jvm ×1
jython ×1
maven ×1
profiling ×1
spring-mvc ×1