java线程泄露_面试官:小伙子先来说一下可能引起Java内存泄露的场景吧
原標題:面試官:小伙子先來說一下可能引起Java內存泄露的場景吧
本文分析一下可能引起java內存泄露的場景:
通過 finalize 方法
終結器finalizers的使用是潛在內存泄漏問題的另一個來源。每當類的finalize方法被重寫時,該類的對象不會立即被垃圾回收。相反,GC將它們排隊等待最后確定,這將在稍后的時間點發生。
另外,如果我們的應用程序不能更快地完成或最終處理一個錯誤,那么如果我們的應用程序不能更快地完成一個錯誤,那么我們的應用程序就不能完成。
為了證明這一點,讓我們考慮一下,我們已經為一個類重寫了finalize方法,并且該方法需要一點時間來執行。當此類的大量對象被垃圾回收時,在VisualVM中,它看起來像:
但是,如果我們只刪除重寫的finalize方法,則同一個程序會給出以下響應:
如何預防?
我們應該避免使用終結器
內部字符串
當Java 7從PermGen轉移到HeapSpace時,Java字符串池經歷了一次重大變化。但是對于在版本6及以下運行的應用程序,我們在處理大字符串時應該更加注意。
如果我們讀取一個巨大的字符串對象,并在該對象上調用intern,那么它將進入字符串池,該池位于PermGen(永久內存)中,只要我們的應用程序運行,它就會一直留在那里。這會阻塞內存并在我們的應用程序中造成內存泄漏。
JVM 1.6中這個例子的PermGen在VisualVM中如下所示:
與此相反,在一個方法中,如果我們只是從文件中讀取一個字符串,而不是對其進行內接,那么PermGen看起來像:
如何預防?
解決這個問題最簡單的方法是升級到最新的Java版本,因為從JavaVersion7開始,字符串池被移到HeapSpace
如果要處理大型字符串,請增大PermGen空間的大小,以避免任何潛在的OutOfMemoryError:-XX:MaxPermSize=512m
使用ThreadLocals
ThreadLocal是一種構造,它使我們能夠將狀態隔離到特定線程,從而允許我們實現線程安全。
當使用這個結構時,每個線程都將持有一個對其ThreadLocal變量副本的隱式引用,并將維護自己的副本,而不是在多個線程之間共享資源,只要線程是活動的。
盡管ThreadLocal變量有很多優點,但是它的使用還是有爭議的,因為如果使用不當,它們會導致內存泄漏。Joshua Bloch曾經評論過線程本地用法:
線程池的草率使用與線程局部變量的草率使用可能會導致意外的對象保留,正如在許多地方所指出的那樣。但把責任推到線程本地上是沒有道理的。
threadlocal導致內存泄漏
一旦保持線程不再活動,threadlocal就應該被垃圾回收。但是當 threadlocal與現代應用服務器一起使用時,問題就出現了。
現代應用服務器使用一個線程池來處理請求,而不是創建新的請求(例如apache tomcat中的Executor)。此外,它們還使用單獨的類加載器。
由于應用程序服務器中的線程池遵循線程重用的概念,因此它們永遠不會被垃圾回收,而是被重用以服務于另一個請求。
現在,如果任何類創建了一個ThreadLocal變量,但沒有顯式地刪除它,那么即使在web應用程序停止之后,該對象的副本也將保留在工作線程中,從而防止對象被垃圾回收。
如何預防?removeThreadLocals.set(null) try { threadLocal.set(System.nanoTime); //... further processing}finally { threadLocal.remove;} 解決內存泄漏的其他方法
雖然在處理內存泄漏時沒有一刀切的解決方案,但是我們可以通過一些方法將這些泄漏最小化。
啟用分析
Java探查器是監視和診斷應用程序內存泄漏的工具。它們分析應用程序內部發生的事情—例如,如何分配內存。
使用探查器,我們可以比較不同的方法,并找到可以最佳利用資源的領域。
在本教程我們一直在使用javavisualvm。請查看我們的Java探查器指南,了解不同類型的探查器,如任務控制、JProfiler、YourKit、Java VisualVM和Netbeans探查器。
詳細的垃圾收集
通過啟用詳細的垃圾收集,我們可以跟蹤GC的詳細跟蹤。要實現這一點,我們需要在JVM配置中添加以下內容:
-verbose:gc
通過添加此參數,我們可以看到GC內部發生的詳細情況:
使用引用對象以避免內存泄漏
我們還可以使用Java中內置的引用對象java.lang.ref處理內存泄漏的包。使用java.lang.ref包,而不是直接引用對象,我們使用對對象的特殊引用,以便于對它們進行垃圾回收。
引用隊列旨在讓我們知道垃圾回收器執行的操作。
Eclipse內存泄漏警告
對于jdk1.5及更高版本的項目,每當遇到明顯的內存泄漏情況時,Eclipse都會顯示警告和錯誤。因此,在Eclipse中開發時,我們可以定期訪問“Problems”選項卡,并對內存泄漏警告(如果有)保持警惕:
Benchmarking基準測試
我們可以通過執行基準測試來測量和分析Java代碼的性能。這樣,我們就可以比較不同方法的性能來完成相同的任務。這可以幫助我們選擇更好的方法,也可以幫助我們保存記憶。
有關基準測試的更多信息,請訪問我們的Java微基準標記教程。
代碼評審
最后,我們總是采用經典的、老派的方法來完成簡單的代碼遍歷。
在某些情況下,即使是這種看起來微不足道的方法也有助于消除一些常見的內存泄漏問題。
結論
通俗地說,我們可以認為內存泄漏是一種通過阻塞重要內存資源而降低應用程序性能的疾病。而且,與所有其他疾病一樣,如果得不到治愈,隨著時間的推移,它會導致致命的應用程序崩潰。
內存泄漏很難解決,找到它們需要對Java語言進行復雜的掌握。在處理內存泄漏時,沒有一刀切的解決方案,因為泄漏可以通過各種各樣的事件發生。
但是,如果我們求助于最佳實踐并定期執行嚴格的代碼遍歷和分析,那么我們就可以將應用程序中內存泄漏的風險降到最低。
原文鏈接:http://javakk.com/911.html
如果覺得本文對你有幫助,可以轉發關注支持一下返回搜狐,查看更多
責任編輯:
總結
以上是生活随笔為你收集整理的java线程泄露_面试官:小伙子先来说一下可能引起Java内存泄露的场景吧的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java课程设计 成绩_Java课程设计
- 下一篇: libsvm java下载_java-l