2015-04-02 68 views
29

我有一個J2EE應用程序,有一些有趣的行爲......堆似乎表現良好,隨着時間的推移,垃圾集合正在不斷增長和萎縮。沒有可觀的整體長期堆擴展。然而,metaspace以每小時20 Mb的速度穩步增長,直到我們擊中MaxMetaspace並遇到OOME。我已經嘗試了並行和G1垃圾收集器(jdk1.8.0_40)。如何診斷Java 8元空間泄漏?

應用程序在執行過程中沒有得到重新部署,所以它看起來不像是典型的類加載器泄漏。有沒有人有關於如何追蹤這種泄漏的來源的建議?

+0

你是否找到任何答案? – 2015-08-11 15:56:47

+0

你能提供更多的信息:JEE服務器,使用過的庫。 – sibnick 2015-08-17 17:16:27

+1

這是試圖在Java 8下的JBoss 4.2.3.GA上運行遺留的J2EE應用程序。這不是受支持的配置,但客戶端真的想嘗試它。我知道從那時起JBoss類加載發生了重大變化,所以我懷疑是類加載器問題。菲利普關於代理人代的猜測可能有一些優點。我們最終決定「咬緊牙關」,將應用程序移植到Wildfly 8. – 2015-08-19 03:25:47

回答

3

主要原因爲java.lang.OutOfMemoryError:元空間是:

  • 太多的級別
  • 太大類被加載到元空間。

如果要重現問題使用此代碼片段:

public class Metaspace { 
static javassist.ClassPool cp = javassist.ClassPool.getDefault(); 

public static void main(String[] args) throws Exception { 
    for (int i = 0; ; i++) { 
     Class c = cp.makeClass("eu.plumbr.demo.Generated" + i).toClass(); 
    } 
    } 
} 

所有這些生成的類定義最終耗時元空間。

Javaassist在Maven repo

你可以找到許多關於OOME here

3

做一個堆轉儲與Eclipse MAT進行分析。看看你已經加載的類。檢查是否有意想不到的事情,尤其是重複的類。它也有一個類加載器資源管理器。

編輯: 理論上你也可以是你不斷地生成代理。

+1

我們嘗試了MAT classloader資源管理器。不幸的是,該應用程序非常繁忙且複雜,並且泄漏速度足夠慢,以至於它仍然是「大海撈針」主題。無論如何,這種配置的目的是成爲臨時解決方案,並且我們達到了收益遞減的地步,所以我們放棄了。 – 2015-08-19 03:32:00

+0

我不知道WildFly問題。 OP從來沒有調試過這個問題,所以它可能是任何東西,包括他/她的應用程序。 – 2017-08-29 19:04:07