2011-08-04 62 views
1

我公司最近已將其作爲內容管理解決方案遷至Alfresco。由於某些內容是動態的(一個包含在另一個.jsp中的.jsp文件從Alfresco 中讀取以xml形式發佈的站點地圖,並將結果緩存24小時),生成的文件是.jsp,並且是rsync的,我們的Sun Web Server 7 servlet容器。Sun Web Server 7服務.jsp - 伊甸園空間行爲 - 可能的內存泄漏

每個頁面都有一個標題,一個菜單和一個腳註,其中包含使用jsp:include運行時指令的 。我的理解是,當第一次請求index.jsp時,會有一些編譯的jsps例如index.class,header.class, menu.classfooter.class。需求是讓這些servlet容器每隔x秒檢查一次源jsps(由Alfresco推出)的修改。

本身已經configred web服務器(default-web.xml)所推薦的孫文檔是生產就緒以下參數:

<init-param> 
    <param-name>development</param-name> 
    <param-value>false</param-value> 
</init-param> 
<init-param> 
    <param-name>checkInterval</param-name> 
    <param-value>0</param-value> 
</init-param> 
    <init-param> 
    <param-name>fork</param-name> 
<param-value>true</param-value> 
</init-param> 
<init-param> 
    <param-name>mappedfile</param-name> 
    <param-value>false</param-value> 
</init-param> 
<init-param> 
    <param-name>suppressSmap</param-name> 
    <param-value>true</param-value> 
</init-param> 
<init-param> 
    <param-name>classdebuginfo</param-name> 
    <param-value>false</param-value> 
</init-param> 
<init-param> 
    <param-name>trimSpaces</param-name> 
    <param-value>true</param-value> 
</init-param> 

注意,checkInterval參數應設置爲60,但這樣做導致Web服務器無法啓動(我一直無法弄清楚爲什麼)。不幸的解決方法是 ,然後將development設置爲true,這是我想避免的。

servlet容器配置了以下JVM設置(再次建議由Sun文檔):

-server -Xrs -Xmx2048m -Xms2048m -Xmn2024m -XX:+AggressiveHeap -XX:LargePageSizeInBytes=256m -XX:+UseParallelOldGC -XX:+UseParallelGC -XX:ParallelGCThreads=8 -XX:+DisableExplicitGC 

在性能測試中,我們所看到的伊甸園空間經常扣球至2GB(我們的靜態的總大小內容大約是200MB,我們的 測試是針對少數幾頁的)。結果在很多次要收藏中;將物體快速推入終身空間,並且它永遠不會真正恢復,導致出現很多頻繁的完整GC。(倖存者空間也從90MB縮小爲2個字節,我只能假設Eden空間聲稱它是自己的 - 任何人都可以證實?) 。這是我們最大的問題標誌;我們的開發者 都沒有認爲這是正常的行爲,但我們無法解釋內存的去向。

Snapshot of Eden space under load

我們所看到的另一個問題是線程數。由於每個http請求都會導致servlet產生一個新的線程,我認爲它會與負載成比例上升(我也認爲在運行時執行jsp:include時,在每個servlet中也會創建一個新線程 (編譯父級jsp中的RequestDispatcher.include() )但是,一旦每個請求被服務,線程就會死亡,並且一個新的線程會死在它的位置 這是一個正確的假設嗎?線程計數似乎停止和增長,不管負載如何。

任何幫助將

回答

2

堆使用圖中的鋸齒模式是正常的,並不表示內存泄漏。只有當鋸齒波下限趨於上升時纔會顯示內存泄漏隨着時間的推移。

但是,始終執行完整GC是一個問題,這可能表示存儲泄漏。嘗試使用內存分析器運行以查看是否可以發現泄漏的內容。

我有一種感覺,我知道什麼可能會導致泄漏。我想你說你是動態生成JSP的。每當容器找到新的(或更新的)JSP時,它就會生成Java類,編譯類並加載字節碼。如果你不小心,舊的類/舊版本的類將保持可及並泄漏。


我也不希望線程數隨着負載上升和下降。一個體面的Web容器將維護用於處理傳入請求的線程池。線程池通常具有固定的上限,這樣請求風暴不會導致線程數量的爆炸,從而導致資源使用和爭用問題。

+0

我同意預期的模式是上面描述的模式,但是我擔心峯值是在年輕一代規模的限制下,因爲servlet容器所做的工作實際上很少。 – pertinky

+0

另外,關於動態重新編譯;根據一些Jasper2文檔,在JVM中運行的javac ant任務中存在內存泄漏,建議您使用'fork = true'在單獨的JVM進程中編譯jsps。上面的圖來自一個不分叉的web服務器,而且我現在正在運行一個forking,看看是否有所作爲。 – pertinky