java內存泄漏


一、什么是內存泄漏

  開發中,都能遇到或者聽過兩種關於java內存的異常情況:內存溢出(out of memory)和內存泄漏(memory leak)。

  內存溢出指的是程序需要申請新的內存時,沒有足夠大小的內存空間供其使用。常見類型:

    1、java.lang.OutOfMemoryError: Java heap space  堆內存溢出   解決辦法:通過-Xmn(最小值)–Xms(初始值) -Xmx(最大值)參數手動設置 Heap(堆)的大小

    2、 java.lang.StackOverflowError 棧溢出  解決辦法:通過Xss參數調整大小

    3、 java.lang.OutOfMemoryError: PermGen space  解決辦法:通過MaxPermSize參數設置PermGen space大小

  內存泄漏指的是程序申請內存后,當不再使用時,本該被回收卻始終無法釋放或是不能及時的釋放已申請的內存空間。內存泄漏,如果數量龐大,最終是會導致內存溢出的。

  對用戶來說,內存泄漏並不會產生什么危害。程序代碼、運行對用戶是完全透明的,真正的危害性在於內存泄漏可能導致的最終的內存溢出,程序崩潰終止。

  這里,java開發人員一般會有疑問:既然java存在GC,為什么還會發生內存泄漏?

  簡單說說GC的回收:

    java GC會監控所有堆中創建的對象的運行狀況,監控對象是否可達(從GC Roots根開始向下搜索),如果對象不可達,則其就可以被GC回收。GC由jvm自動執行,不可人為干預(System.gc()方法只是建議jvm去執行回收動作,並不能確定一定會即時的去執行)

  內存泄漏為什么發生:

    實際的開發過程中,可能會存在着無用但可達的對象,這些對象不能被GC回收,所以就導致了內存泄漏的產生。

二、java中案例

  1、靜態集合類中存儲對象

    static List<Object> list = new ArrayList<>();
    
    public static void main(String[] args) {
        for(int i =0; i<10; i++){
            Object object = new Object();
            list.add(object);
            object = null;
        }
        
    }

  靜態集合類中,循環申請對象放入集合中。后面僅僅是對新申請的對象置null,並不能引起GC對於這個對象的回收,因為集合類仍然對其保持着引用,

  也就是可達的(list引用指向的內存空間中存在指向 Object 對象的引用)。如果后面的程序中,不再使用集合list,則這就產生了內存溢出。一般好的習慣,不使用的集合clear,然后置為null。

  2、單例模式

    單例的生命周期和應用程序是一樣長的,所以單例程序中,如果持有對外部對象的引用的話,那么這個外部對象是不能被回收的,則會導致內存泄漏的產生。

  3、一些提供close的資源未關閉導致內存泄漏

    數據庫連接(dataSourse.getConnection()),網絡連接(socket)和io連接必須手動close,否則是不能被回收的。

  


免責聲明!

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



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