2016-02-29 104 views
-1

我的web應用程序中有一個靜態的ThreadLocal對象,在處理請求之前,我正在使用web servlet過濾器類中的某個默認值進行初始化。在應用程序中,其他幾個類(如處理器)使用並更新其值。我已閱讀過一些文章,使用ThreadLocal創建的對象仍然與線程關聯,儘管請求過程已完成,因爲線程維護在由容器管理的池中。如果不從ThreadLocal變量中移除對象,這會導致內存泄漏。哪個是刪除Thread Local對象引用的最好方法

我在這方面有兩個問題。

  1. 在下面的選項中,哪一個是刪除其引用以防止內存泄漏的最佳方法。

    ThreadLocal obj; 
    1) obj.remove(); // remove the contents of ThreadLocal. 
    2) obj.set(""); // set some default value 
    3) obj.set(null); // set null 
    
+0

對(1)的回答是(1),或讓線程退出。第二個問題是不可理解的。 – EJP

+0

轉載了我的第二個問題? – kswaughs

回答

1

使用ThreadLocal#remove()。但這不是你主要關心的問題。您主要關心的應該是您可以保證在特殊情況下也會調用remove()。執行此操作的正確方法是在創建和委派TLS的try塊的finally中執行remove()

YourContext context = null; 
try { 
    context = YourContext.create(request, response); 
    chain.doFilter(request, response); 
} finally { 
    if (context != null) context.release(); // Invokes remove(). 
} 

如果你已經對Java的7+,更好的是讓你的背景下實現AutoCloseable由此close()調用remove()然後用try-with-resources塊。

try (YourContext context = YourContext.create(request, response)) { 
    chain.doFilter(request, response); 
} 

更多提示如何創建YourContext,頭Retrieving Web Session from a POJO Outside the Web Container

+0

我仍然使用Java 6和In Filter類,我正在初始化並在鏈調用之前和之後移除。你能幫我解答我的第二個問題嗎? – kswaughs

+0

如回答,必須在finally塊中刪除。至於第二個問題,你應該問每個問題一個問題。 GC事宜至少與TLS事宜無關。如果一個對象沒有任何引用,它就符合GC的條件。就那麼簡單。 – BalusC

相關問題