【问题标题】:Ehcache - PermGen memory leak when using replicationEhcache - 使用复制时 PermGen 内存泄漏
【发布时间】:2014-05-13 13:23:26
【问题描述】:

我使用 Ehcache 作为 Hibernate 二级缓存的提供者。如果没有复制,一切正常,但是一旦我添加复制,在 Tomcat 7 上重新部署时就会出现类加载器内存泄漏。

起初我尝试使用以下 ehcache.xml 进行 RMI 复制:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <cacheManagerPeerProviderFactory
        class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
        properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446"/>

    <cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

    <defaultCache maxElementsInMemory="10">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>
    </defaultCache>

</ehcache>

我注意到在几次重新部署后,我得到了 PermGen 内存不足错误。我使用 VisualVM 找到了根本原因。这是来自根目录的路径:

this     - value: org.apache.catalina.loader.WebappClassLoader #2
 <- <classLoader>     - class: net.sf.ehcache.distribution.ConfigurableRMIClientSocketFactory, value: org.apache.catalina.loader.WebappClassLoader #2
  <- <class>     - class: net.sf.ehcache.distribution.ConfigurableRMIClientSocketFactory, value: net.sf.ehcache.distribution.ConfigurableRMIClientSocketFactory class ConfigurableRMIClientSocketFactory
   <- csf     - class: sun.rmi.transport.tcp.TCPEndpoint, value: net.sf.ehcache.distribution.ConfigurableRMIClientSocketFactory #1
    <- key     - class: java.util.HashMap$Entry, value: sun.rmi.transport.tcp.TCPEndpoint #5
     <- [12]     - class: java.util.HashMap$Entry[], value: java.util.HashMap$Entry #12867
      <- table     - class: java.util.HashMap, value: java.util.HashMap$Entry[] #1002 (16 items)
       <- localEndpoints (sticky class)     - class: sun.rmi.transport.tcp.TCPEndpoint, value: java.util.HashMap #1192

然后我决定尝试 JGroups 而不是 RMI:

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">

    <cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"/>

    <defaultCache maxElementsInMemory="10">
        <cacheEventListenerFactory class="net.sf.ehcache.distribution.jgroups.JGroupsCacheReplicatorFactory"/>
    </defaultCache>

</ehcache>

但最终还是遇到了同样的问题!

this     - value: org.apache.catalina.loader.WebappClassLoader #2
 <- <classLoader>     - class: org.jgroups.protocols.TP$1, value: org.apache.catalina.loader.WebappClassLoader #2
  <- <class>     - class: org.jgroups.protocols.TP$1, value: org.jgroups.protocols.TP$1 class TP$1
   <- [0]     - class: java.lang.ThreadGroup[], value: org.jgroups.protocols.TP$1 #1
    <- groups     - class: java.lang.ThreadGroup, value: java.lang.ThreadGroup[] #2 (4 items)
     <- group (thread object)     - class: java.lang.Thread, value: java.lang.ThreadGroup #1

如您所见,JGroups 的原因不同,但结果是一样的 - OutOfMemoryError: PermGen space。

我尝试将 Ehcache 移动到 Tomcat lib 目录并将 net.sf.ehcache.constructs.web.ShutdownListener 添加到 web.xml,但没有帮助。

我正在使用 ehcache-core 2.6.8 和 ehcache-jgroupsreplication 1.7。

【问题讨论】:

    标签: hibernate memory-leaks classloader ehcache permgen


    【解决方案1】:

    RMI 的问题似乎是由与JDK-8025071 类似的错误引起的,显然无法在关机时清除哈希图,因此没有已知的解决方法。

    JGroups 的问题似乎是JGRP-1576。使用此leak preventor 解决了此问题。所以我会说带有防漏器的 JGroups 是你最好的选择,如果关闭 tomcat 进程并重新启动不是一个选项。

    这样做将花费与重新部署相同的时间,并解决这些问题以及将来在项目中升级库时可能出现的其他问题。

    【讨论】:

    • 感谢您的链接!原来ehcache-jgroupsreplication 使用的是旧版本的jgroups - 3.1.0,它存在 JGRP-1576 中描述的泄漏问题。我已将 jgroups 更新到最新版本 (3.4.3) 并修复了泄漏!
    猜你喜欢
    • 2015-12-25
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-07-31
    • 2020-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多