轉載自html
https://blog.csdn.net/goodlixueyong/article/details/40716779 java
https://blog.csdn.net/vshuang/article/details/39647167android
上面的幾個參數是與虛擬機的內存分配相關的,虛擬機的內存分配過程是下面這樣的:程序員
1 首先判斷一下須要申請的size是否是過大,若是申請的size超過了堆的最大限制,則轉入步驟6數據庫
2 嘗試分配,若是成功則返回,失敗則轉入步驟3數組
3 判斷是否gc正在進行垃圾回收,若是正在進行則等待回收完成以後,嘗試分配。若是成功則返回,失敗則轉入步驟4緩存
4 本身啓動gc進行垃圾回收,這裏gcForMalloc的參數是false。因此不會回收軟引用,回收完成後嘗試分配,若是成功則返回,失敗則轉入步驟5安全
5 調用dvmHeapSourceAllocAndGrow嘗試分配,這個函數會擴張堆。因此heap startup的時候能夠給一個比較小的初始堆,實在不夠用再調用它進行擴張網絡
6 進入回收軟引用階段,這裏gcForMalloc的參數是ture,因此須要回收軟引用。而後調用dvmHeapSourceAllocAndGrow嘗試分配,若是失敗則拋出OOM。框架
1.靜態集合類像HashMap、Vector等的使用最容易出現內存泄露,這些靜態變量的生命週期和應用程序一致,全部的對象Object也不能被釋放,由於他們也將一直被Vector等應用着。
Static Vector v = new Vector(); for (int i = 1; i<100; i++) { Object o = new Object(); v.add(o); o = null; }
在這個例子中,代碼棧中存在Vector 對象的引用 v 和 Object 對象的引用 o 。在 For 循環中,咱們不斷的生成新的對象,而後將其添加到 Vector 對象中,以後將 o 引用置空。問題是當 o 引用被置空後,若是發生 GC,咱們建立的 Object 對象是否可以被 GC 回收呢?答案是否認的。由於, GC 在跟蹤代碼棧中的引用時,會發現 v 引用,而繼續往下跟蹤,就會發現 v 引用指向的內存空間中又存在指向 Object 對象的引用。也就是說盡管o 引用已經被置空,可是 Object 對象仍然存在其餘的引用,是能夠被訪問到的,因此 GC 沒法將其釋放掉。若是在此循環以後, Object 對象對程序已經沒有任何做用,那麼咱們就認爲此 Java 程序發生了內存泄漏。
2.各類鏈接,數據庫鏈接,網絡鏈接,IO鏈接等沒有顯示調用close關閉,不被GC回收致使內存泄露。
3.監聽器的使用,在釋放對象的同時沒有相應刪除監聽器的時候也可能致使內存泄露。