1. 程式人生 > >java記憶體洩露

java記憶體洩露

Java的最顯著的優點之一是記憶體管理。你只需要簡單建立物件,java的垃圾收集器來負責分配和釋放記憶體。但是,情況並不是這麼簡單,因為java程式中常發生記憶體洩露。

記憶體洩露:應用程式不再使用物件,但是垃圾回收器無法將其刪除,因為它們被引用

在下面的例子中,物件A引用物件B。
當B在應用程式中不再被使用時,A仍然保留對它的引用。這樣垃圾收集器不能從記憶體中刪除B。下面的情況造成記憶體洩露:

靜態集合類

在使用Set、Vector、HashMap等集合類的時候需要特別注意,有可能會發生記憶體洩漏。當這些集合被定義成靜態的時候,由於它們的生命週期跟應用程式一樣長,這時候,就有可能會發生記憶體洩漏,看下面程式碼:

class StaticTest
{
    private static Vector v = new Vector(10);

    public void init()
    {
        for (int i = 1; i < 100; i++)
        {
            Object object = new Object();
            v.add(object);
            object = null;
        }
    }
}

在上面的程式碼中,迴圈申請了Object物件,並新增到Vector中,然後將物件設定為null

,可是這些物件因為被Vector引用著,因此並不能被GC回收,因此造成了記憶體洩漏。因此,要釋放這些物件,還需要被它們從Vector刪除,最簡單的方法就是將Vector設定為null

集合裡的物件屬性值被改變

public static void main(String[] args)
{
    Set<Student> set = new HashSet<Student>();
    Student s1 = new Student("Jack");
    Student s2 = new Student("Mary");
    Student s3 = new Student("Eason");

    set.add(s1);
    set.add(s2);
    set.add(s3);

    System.out.println(set.size());//3
    s2.setName("Jackson"); //修改屬性,此時s2元素對應的hashcode值發生改變
    set.remove(s2);        // remove不掉,造成記憶體洩漏
    set.add(s2);           // 新增成功

    System.out.println(set.size());//4
}

在這個例子中,由於物件s2的屬性值被改變了,因此不能從set中刪除,所以set中會一直保持著s2的引用,不能被回收,造成了記憶體洩漏。

監聽器

在Java中,我們經常會使用到監聽器,如對某個控制元件新增單擊監聽器addOnClickListener(),但往往釋放物件的時候會忘記刪除監聽器,這就有可能造成記憶體洩漏。好的方法就是,在釋放物件的時候,應該記住釋放所有監聽器,這就能避免了因為監聽器而導致的記憶體洩漏。

各種連線

Java中的連線包括資料庫連線、網路連線和io連線,如果沒有顯式呼叫其close()方法,是不會自動關閉的,這些連線就不能被GC回收而導致記憶體洩漏。一般情況下,在try程式碼塊裡建立連線,在finally裡釋放連線,就能夠避免此類記憶體洩漏。

外部模組的引用

呼叫外部模組的時候,也應該注意防止記憶體洩漏。如模組A呼叫了外部模組B的一個方法,如:
public void register(Object o)
這個方法有可能就使得A模組持有傳入物件的引用,這時候需要檢視B模組是否提供了去除引用的方法,如unregister()。這種情況容易忽略,而且發生了記憶體洩漏的話,比較難察覺,應該在編寫程式碼過程中就應該注意此類問題。

單例模式

使用單例模式的時候也有可能導致記憶體洩漏。因為單例物件初始化後將在JVM的整個生命週期記憶體在,如果它持有一個外部物件(生命週期比較短)的引用,那麼這個外部物件就不能被回收,而導致記憶體洩漏。如果這個外部物件還持有其它物件的引用,那麼記憶體洩漏會更嚴重,因此需要特別注意此類情況。這種情況就需要考慮下單例模式的設計會不會有問題,應該怎樣保證不會產生記憶體洩漏問題。


相關推薦

Java記憶體洩露與定位

1、為什麼會發生記憶體洩漏 Java如何檢測內在洩漏呢?我們需要一些工具進行檢測,並發現記憶體洩漏問題,不然很容易發生down機問題。 編寫java程式最為方便的地方就是我們不需要管理記憶體的分配和釋放,一切由jvm來進行處理,當java物件不再被應用時,等到堆記憶體不夠用時,jvm會進行垃

排查Java 記憶體洩露-藉助排查工具

轉自:https://juejin.im/entry/57fb07255bbb50005b2f20ac java記憶體洩露典型特徵 現象一: 堆/Perm 區不斷增長, 沒有下降趨勢(回收速度趕不上增長速度), 最後不斷觸發FullGC, 甚至crash(如下**兩張圖是同一

JAVA 記憶體洩露詳解-值得收藏的好文

非常好的文章, 轉載自:http://blog.csdn.net/anxpp/article/details/51325838     Java的一個重要特性就是通過垃圾收集器(GC)自動管理記憶體的回收,而不需要程式設計師自己來釋放記憶體。理論上Java

java 記憶體洩露

一、java相對於C++來說很難記憶體洩露,因為有自己的垃圾回收機制。如果想知道java出現記憶體洩露,最好先了解java是如何管理記憶體的。Java的記憶體管理就是物件的分配和釋放問題。在Java中,程式設計師需要通過關鍵字new為每個物件申請記憶體空間 (基本型別除外),

詳解java記憶體洩露和如何避免記憶體洩漏

源地址:http://www.xttblog.com/?p=518 一直以來java都佔據著語言排行榜的頭把交椅。這是與java的設計密不可分的,其中最令大家喜歡的不是面向物件,而是垃圾回收機制。你只需要簡單的建立物件而不需要負責釋放空間,因為Java的垃圾回收器會負責記憶

分析和解決JAVA 記憶體洩露的實戰例子

這幾天,一直在為Java的“記憶體洩露”問題糾結。Java應用程式佔用的記憶體在不斷的、有規律的上漲,最終超過了監控閾值。福爾摩 斯不得不出手了! 分析記憶體洩露的一般步驟     如果發現Java應用程式佔用的記憶體出現了洩露的跡象,那麼我們一般採用下面的步驟分

JAVA記憶體洩露分析和解決方案及WINDOWS自帶檢視工具

Java記憶體洩漏是每個Java程式設計師都會遇到的問題,程式在本地執行一切正常,可是佈署到遠端就會出現記憶體無限制的增長,最後系統癱瘓,那麼如何最快最好的檢測程式的穩定性,防止系統崩盤,作者用自已的親身經歷與各位分享解決這些問題的辦法.作為Internet最流行的程式語言之一,Java現正非常流行.我們的網

java記憶體洩露

Java的最顯著的優點之一是記憶體管理。你只需要簡單建立物件,java的垃圾收集器來負責分配和釋放記憶體。但是,情況並不是這麼簡單,因為java程式中常發生記憶體洩露。記憶體洩露:應用程式不再使用物件,但是垃圾回收器無法將其刪除,因為它們被引用。在下面的例子中,物件A引用物件

Java 記憶體洩露監控工具-- JVM監控工具介紹jstack, jconsole, jinfo, jmap, jdb, jstat

u              jstack的用法 如果java程式崩潰生成core檔案,jstack工具可以用來獲得core檔案的java stack和native stack的資訊,從而可以輕鬆地知道java程式是如何崩潰和在程式何處發生問題。另外,jstack工具還可以附屬到正在執行的java程式中,看

Java記憶體洩露的一個小例子

Java記憶體洩露     一般來說記憶體洩漏有兩種情況。一種情況如在C/C++語言中的,在堆中的分配的記憶體,在沒有將其釋放掉的時候,就將所有能訪問這塊記憶體的方式都刪掉(如指標重新賦值);另一種情況則是在記憶體物件明明已經不需要的時候,還仍然保留著這塊記憶體和它的訪問方式(引用)。第一種情況,在Ja

Java記憶體洩露監控工具:JVM監控工具介紹

jstack -- 如果java程式崩潰生成core檔案,jstack工具可以用來獲得core檔案的java stack和native stack的資訊,從而可以輕鬆地知道java程式是如何崩潰和在程式何處發生問題。另外,jstack工具還可以附屬到正在執行的java程式中,看到 當時執行的java程式的

Java 記憶體洩露 Memory Leak(Oracle官方文件)

The jmap -permgen command prints statistics for the objects in the permanent generation, including information about internalized String instances. S

JAVA 記憶體洩露詳解(原因、例子及解決)

  Java的一個重要特性就是通過垃圾收集器(GC)自動管理記憶體的回收,而不需要程式設計師自己來釋放記憶體。理論上Java中所有不會再被利用的物件所佔用的記憶體,都可以被GC回收,但是Java也存在記憶體洩露,但它的表現與C++不同。 JAVA 中的記憶體管理

Java記憶體洩露原因詳解

###http://www.zhihu.com/people/7e55pu04ed/asks### ###http://www.zhihu.com/people/7e55pu04ed/answers### ###http://www.zhihu.com/people/7e55pu04ed/posts### #

JAVA】談談記憶體洩露

                                          &

Java記憶體管理之記憶體洩露是什麼?什麼情況下會導致記憶體洩露

文章目錄 1. 靜態類的使用 2. 資源連線的使用 3. 監聽器的使用 雖然Java擁有垃圾回收機制,但同樣會出現記憶體洩露問題,我們說一下比較主要的三種情況。 1. 靜態類的使用 諸如 HashMap、Vector 等集

Java虛擬機器7:記憶體溢位和記憶體洩露、並行和併發、Minor GC和Full GC、Client模式和Server模式的區別

記憶體溢位和記憶體洩露的區別 1、記憶體溢位 記憶體溢位指的是程式在申請記憶體的時候,沒有足夠大的空間可以分配了。 2、記憶體洩露 記憶體洩露指的是程式在申請記憶體之後,沒有辦法釋放掉已經申請到記憶體,它始終佔用著記憶體,即被分配的物件可達但無用。記憶體洩露一般都是因

使用Handler容易產生的記憶體洩露以及介紹下Java的4種引用

最近時間都利用的不太好,都是到下午才開始學習或者做事,一上午都吹B或者XXX用掉了。。。不太好,這裡督促下自己不要再懶惰,哈哈!! 廢話不多說,今天來講下一個“經常”遇到的一個記憶體洩露的情況來引出想提的Java的4種引用方式 在舉例子之前先將一些基礎的知識,不然

記一次尷尬的Java應用記憶體洩露排查

這星期被線上JVM記憶體佔用不斷增大的問題所困擾,自己提出了一些假設,然後去實施驗證都一一失敗了,有一些經驗和教訓在這裡分享下. 之所以是尷尬,是最後因為偶爾出現修復了另一個問題導致記憶體不再上升,但這之間的關係還未明瞭,還需要繼續追蹤. 這裡講述一下這次排查的過程. 直接記憶體的錯誤判斷 伺服器的JVM配

java記憶體管理關係及記憶體洩露 原理

這可能是最近寫的部落格中最接近底層的了。閒言少敘,進入正題。 java物件和記憶體的關係 首先,我們要知道下面幾條真理(自己總結的) 一個完整的建立物件流程是 1宣告物件,2開闢記憶體空間,3將物件和記憶體空間建立聯絡。 一個物件只能對應一個記憶體空間,