2014-04-02 40 views
1

我正在使用Ehcache作爲Hibernate的二級緩存提供程序。如果沒有複製一切工作正常,但只要我添加複製我得到的類加載器的內存泄漏在Tomcat 7重新部署Ehcache - 使用複製時PermGen內存泄漏

起初,當我試着用以下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的空間。

我試過將Ehcache移動到Tomcat的lib目錄下,並且將net.sf.ehcache.constructs.web.ShutdownListener添加到web.xml,但它沒有幫助。

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

回答

2

RMI的問題似乎是由於類似於此錯誤JDK-8025071的錯誤導致的,顯然無法在關閉時清除散列映射,因此沒有解決方法。

JGroups的問題似乎是JGRP-1576。此問題已通過使用此leak preventor修復。所以我想說JGroups的防泄漏是最好的選擇,如果關閉tomcat進程並且重啓不是一個選項。

這樣做與重新部署大致相同,並且解決了將來圖書館在項目中升級時可能出現的這些和其他未來問題。

+0

感謝您的鏈接!原來'ehcache-jgroupsreplication'使用的是舊版本的'jgroups' - 3.1.0,它存在JGRP-1576中描述的泄漏問題。我已經更新了'jgroups'到最新版本(3.4.3),並修正了泄漏! – John29