JVM內存泄漏導致內存溢出(OOM)的場景


一、概念

1. 內存泄漏:對象使用完之后,沒有按照預期被GC回收,一直留在內存中

2. 內存溢出:大量對象一直留在內存中,導致內存不夠用(OOM),影響正常的程序運行

 

二、內存泄漏的場景

1. 內存中數據量太大,比如一次性從數據庫中取出來太多數據

2. 靜態集合類中對對象的引用,在使用完后未清空(只把對象設為null,而不是從集合中移除),使JVM不能回收,即內存泄漏

3. 靜態方法中只能使用全局靜態變量,而如果靜態變量又持有靜態方法傳入的參數對象的引用,會引起內存泄漏

4. 代碼中存在死循環,或者循環過多,產生過多的重復的對象

5. JVM啟動參數內存值設置過小

a. 堆內存:JVM默認為64M,-Xms堆的最小值, -Xmx堆的最大值,OutOfMemoryError: java heap space

b. 棧內存:-Xss,StackOverflowError,棧太深

c. 永久代內存:-XX:PermSize,-XX:MaxPermSize,OutOfMemoryError: PermGen space,加載的類過多

6. 監聽器:addXXListener,沒有remove

7. 各種連接沒有關閉:例如數據庫連接、網絡連接

8. 單例模式:如果單例對象持有外部對象的引用,那么外部對象將不會被回收,引起內存泄漏

9. 一個類含有靜態變量,這個類的對象就無法被回收

10. ThreadLocal

 

三、解決思路

1. 修改JVM啟動參數,直接增加內存

2. 檢查錯誤日志

3. 檢查代碼中有沒有一次性查出數據庫所有數據

4. 檢查代碼中是否有死循環

5. 檢查代碼中循環和遞歸是否產生大量重復對象

6. 檢查List/Map等集合,是否未清除

7. 使用內存查看工具

 

四、代碼優化

1. 主動釋放無用的對象

2. 盡量使用StringBuilder代替String

3. 盡量少用靜態變量,因為靜態變量是類的,GC不會回收

4. 避免創建大對象和同時創建多個對象,例如數組,因為數組的長度是固定的

5. 對象池技術

 

五、JVM堆內存溢出后,其他線程可否繼續工作?

1. 當前線程OOM后,如果終止,會發生GC,其他線程可以繼續工作

2. 如果線程OOM后,沒有終止,其他線程也會OOM

 

 

 

 

https://www.cnblogs.com/200911/p/3965108.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM