2011-03-04 52 views
1

由於JBoss 4.2不支持@EJB注入,因此我使用JNDI查找來引用Servlet所需的EJB。Servlet中的JNDI查找是否會導致permgen內存泄漏?

我擔心這種查找可能會導致JVM中的Permgen非堆內存增長。

據我所知,JNDI是一種動態類加載的形式,所以這可能導致類加載器泄漏。

所以我的問題是,下面的servlet代碼可能會導致隨着時間的推移內存泄漏?

另外,我應該在查找後明確調用InitialContext上的close()方法嗎?由於在這裏實例化的方式(在Servlet中),GC是否有可能無法按預期清理InitialContext?

謝謝。

public class MyServlet extends HttpServlet { 

// JBoss 4.x does not support @EJB injections in servlets (see jndi lookup below) 
@EJB 
private MyService myService; 

private static final String SERVICE_JNDI_NAME = "MyServiceBean"; 

private Logger log = Logger.getLogger(this.getClass().getPackage().getName()); 


public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 

try { 
    // JBoss 4.x does not support @EJB injections in servlets 
    InitialContext ctx = new javax.naming.InitialContext(); 
    myService = (MyService) ctx.lookup(SERVICE_JNDI_NAME); 
} catch (NamingException e) { 
    log.warn("NamingException trying to lookup MyService in context"); 
    throw new RuntimeException(e); 
} 

... 

RequestDispatcher requestDispatcher = request.getRequestDispatcher("/page.jsp"); 
requestDispatcher.forward(request, response); 
} 

}

+1

那麼什麼是阻止你增加permgen內存,因爲它顯然已經不多了?總是添加上下文關閉的塊。 – ThomasRS 2011-03-04 20:06:22

+0

嗨托馬斯,增加permgen上限不會有幫助,因爲目前的泄漏繼續增加。 – 2011-03-04 20:55:37

+0

是的,添加close方法。 – 2011-03-04 21:27:29

回答

0

JNDI是一個目錄查詢服務和Java企業版應用服務器核心技術。除非你有一個錯誤的實現或者有一個不尋常的使用模式的應用程序,否則我會期望因爲JNDI而加載的類最終穩定下來。

無論哪種方式,我強烈建議您使用heap dump analyzer。在您的應用程序運行時拍攝幾張快照,並查看Permgen持續增加時添加的內容。這些信息將直接向您顯示問題所在,或者幫助將根源縮小到更小的區域。

+0

謝謝Kim。泄漏只發生在訪問非常有限的生產系統中。另外,服務器運行的是Java 1.5,並且未安裝jmap和jhat,因此當前的堆轉儲選項是有限的。另外,根據我一直在閱讀的有關permgen泄漏的信息,堆轉儲將提供有關非堆permgen內存內容的有用信息。儘管如此,我的確意識到,我需要找出一些方法來弄清楚泄密的內容。 – 2011-03-04 21:24:25

+0

是的,您在Java 1.5及更早版本中的選擇更加有限。請記住,導致問題的常見原因是泄漏班級裝載機。濫用String.intern()也可能是一個可能的根本原因 – 2011-03-04 21:46:01

相關問題