2013-10-03 30 views
4

我在試圖在我們的Tomcat Java Web應用程序中的內存泄漏的過程中,我想我已經找到了使再三要求我們的JSP中的一個時。但是,在將它拆分爲一個空的JSP後,將其放入運行在jdk1.6上的開箱即用的Tomcat 6.0.37實例中後,我仍然可以看到同樣的結果。Tomcat的JSP請求消耗所有的堆空間

我啓動Tomcat與256M的最大堆大小(-Xmx),和堆由下面我的測試類繞製成282000請求後運行的空間。

爲了便於比較,我還創建了一個HttpServlet的,做同樣的事情作爲JSP和修改了我的測試客戶端調用代替,這將全天運行而不會耗盡內存。

我已經開始嘗試分析堆弄清楚是怎麼回事,但沒有真正成氣候。 Soooo,這是怎麼回事?

測試JSP

<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> 
<%@ page contentType="text/plain"%> 
<% System.out.println("Page requested: " + new Date()); %> 
This is a test response 

Java測試客戶端

public static void main(String[] args) throws Exception { 
    int i=0; 
    while(true) { 
    java.net.URL url = new java.net.URL("http://localhost:8080/test.jsp"); 
    InputStream is = url.openStream(); 
    while(is.read() != -1) { 
     //nothing, just read the stream 
    } 
    is.close(); 
    System.out.println("Requests made: " + i++); 
    } 
} 

回答

5

JSP請求暗中創建HTTP會話。您沒有在HTTP客戶端中維護HTTP會話,因此每個請求都會創建一個全新的HTTP會話。這些會話的過期時間默認爲30分鐘。顯然,所有這些要求都是在30分鐘內解僱的。

,當你在servlet方法做​​request.getSession()你會面臨一個servlet完全相同的問題。

爲了「解決」這個「問題」(在現實世界中不太可能發生這種情況;另一方面,在準備好的Tomcat實例上的282K併發HTTP會話相當可觀),要麼禁用隱式創建HTTP會話JSP:

<%@page session="false"> 

,或者告訴客戶通過之前以下行保持餅乾while循環重複使用相同的HTTP會話:

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL)); 

的另一種方法是減少會話超時,以便服務器在引起堆溢出之前有機會獲得它們,例如,爲5分鐘,在web.xml如下:

<session-config> 
    <session-timeout>5</session-timeout> 
</session-config> 

您可以實現一個HttpSessionListener跟蹤HTTP會話創建和銷燬。

+0

啊啊啊,這是有道理的。我發現堆中的'StandardSession'對象與創建的請求大致相同。你是對的,這不是「真正的世界問題」,但理解這有助於我調整我的測試,希望找到實際問題。 – schmimd04

+0

不客氣。分析器可能會更有助於查找實際問題。 – BalusC