【发布时间】:2021-07-11 23:51:16
【问题描述】:
我们的生产服务器出现 OOM,因为 permgen 已满。使用jmap -permstat查看permgen区域,发现com.sun.xml.ws.client.WSSServiceDelegatingLoader加载了很多类。加载的类是com.sun.proxy.$ProxyXXX,其中XXX 是一个int 序列。
最终,JVM 发生 OOM,full gc 无法回收任何 permgen 内存。 奇怪的是,如果我在 VisualVM 中单击 System GC,则会卸载类并且 permgen 的使用会下降。
我们的JDK版本是1.7.0.80,我们添加了CMSClassUnloadingEnabled。
-XX:+ExplicitGCInvokesConcurrent
-XX:+UseConcMarkSweepGC
-XX:CMSInitiatingOccupancyFraction=60
-XX:+UseParNewGC
-XX:+CMSParalledlRemarkEnabled
-XX:+UseCMSCompactAtFullCollection
-XX:+CMSFullGCsBeforeCompaction=0
-XX:+CMSCLassUnloadingEnabled
-XX:MaxTenuringThreshold=18
-XX:+UseCMSInitialtingOccupancyOnly
-XX:SurvivorRatio=4
-XX:ParallecGCThreads=16
我们的代码已经运行了很长时间。最近的操作是一个 WebLogic 补丁。这真的让我很困惑。有人可以帮我解决这个问题吗,非常感谢!
【问题讨论】:
-
我假设
-XX:ParallelcGCThreads中的拼写错误是这个问题中的复制和粘贴错误? -
是的。原图有水印,所以我手动输入这些选项
-
@XinliNiu 令人惊讶的是,Full GC 无法收集死类加载器,但同样被强制 GC 清理。可以分享一下 GC 日志吗?
-
可能运行到 OutOfMemoryError 的代码正在通过该类加载器主动使用代码加载器。因此,只有在代码不在堆栈中时单击 VisualVM 中的“GC”才能回收类加载器。
-
我们的安全部门通过检测附加了一个代理,该代理启动一个线程并扫描所有加载的类,因此无法回收它们。他们没有通知我并随机开始扫描。当我在visualvm中单击“system gc”时,没有附加代理,因此可以卸载该类,这误导了我。我们的应用确实存在 jax-ws 错误,该错误会在每次 getPotr() 调用时创建一个新代理,但可以正常卸载该类。
标签: garbage-collection jvm weblogic permgen java-memory-leaks