2010-06-04 362 views
6

我們有一個接收SOAP請求的Java應用程序,經過很多請求之後,我們注意到GC停止了世界以卸載大量的GeneratedSerializationConstructorAccessor類。這是一個很大的性能影響。如何避免GeneratedSerializationConstructorAccessor問題?

有誰知道如何避免這種情況,或至少大大減少了創建的GeneratedSerializationConstructorAccessor類的計數?

+0

爲什麼這個標記的gcc(Gnu編譯器集合)?你的意思是把它標記爲gc(垃圾回收器)?你使用gcj(Gnu Compiler for Java)嗎? – 2010-06-04 01:52:54

+0

我認爲這是一個錯字,我將它改爲'gc' – OscarRyz 2010-06-04 01:56:46

回答

0

http://coding.derkeiler.com/Archive/Java/comp.lang.java.programmer/2006-11/msg00122.html

這些類是 反射機制的一部分。由於 對Java 1.3的反射已經由 執行,通過生成類 來執行訪問。它的使用速度更快,但需要更長的時間才能創建,而 會打亂永久生成。

序列化使用它們進行讀/寫 字段,執行方法(的readObject, 的writeObject,readObjectNoData, 的readResolve),並調用 非serialisable基類的構造函數 (這最後的代碼不 可驗證)。

看起來它們只是暫時用來序列化/反序列化給定類的對象。正如文章指出的那樣,這些可能是使用SoftReferences進行的,因此確保您的應用程序具有大量內存,並且這些內存的回收次數會減少。

令人驚訝的是,似乎沒有任何其他解決方案。

5

使用的選項之一:

-Dsun.reflect.inflationThreshold=30 

增加通過構造/方法/技術領域的呼叫的數量的本地訪問之前將「膨脹」到一個生成的訪問。默認值爲15.

-Dsun.reflect.inflationThreshold=0 

完全禁用通貨膨脹。有趣的是,這個選項似乎並不影響構造函數,但它對方法有效。

您可以測試一個簡單的測試應用程序的選項:

public class a { 
    public static void main(String[] args) throws Exception { 
    for (int i = 0; i < 20; i++) { 
     a.class.getDeclaredConstructor(null).newInstance(null); 
    } 
    } 

    private static int x; 
    public a() { 
    new Throwable("" + x++).printStackTrace(); 
    } 
} 

編輯(29日 - 12月2013):-Dsun.reflect.noInflation=true選項禁用通脹機制,而是會立即使用生成的訪問,所以你不要我不想要那個選項。

+1

事實上,將noInflation設置爲true將導致所有訪問都由字節代碼生成完成。您想要將閾值設置爲零或更少。 – 2013-12-29 22:00:13

+1

@raphw你說得對,謝謝你糾正我的錯誤信息!我已經按照你的建議編輯了這篇文章。 – 2013-12-30 00:44:48

2

[...]我們注意到GC停止了世界,卸載了很多 GeneratedSerializationConstructorAccessor類。這是一個很大的表現 的影響。

因爲如果您的應用程序使用反射,這是不可能避免的,您可以嘗試使用CMS garbage collector以儘量減少停止世界GC的影響。