【问题标题】:jvm full gc can't unload classes even permgen is fulljvm full gc 无法卸载类,即使 permgen 已满
【发布时间】: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


【解决方案1】:

这是一个已知的错误https://github.com/javaee/metro-jax-ws/issues/1161

每次创建 JAX-WS 客户端时,例如,使用捆绑在 Weblogic Server 12.1.3 中的库 JAX-WS RI 2.2

com.sun.xml.ws.client.WSServiceDelegate$DelegatingLoader#1

客户端代理类正在加载到类加载器中:

([Loaded com.sun.proxy.$Proxy979 from com.sun.xml.ws.client.WSServiceDelegate$DelegatingLoader] )

解决方案/解决方法: 替换已解决此错误的 JAX-WS 客户端。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 2017-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-26
    相关资源
    最近更新 更多