【发布时间】: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