關於java記憶體泄露的總結--引用的類型:強引用,弱引用,軟引用

來源:互聯網
上載者:User

標籤:jre   垃圾   圖片   lis   主題   範圍   訪問   簡單   記憶體回收   

今天面試了一家公司的java開發方面的實習生,被問到一個問題:如何處理java中的記憶體泄露問題,保證java的虛擬機器記憶體不會被爆掉,當時其實覺得面試官的問題有點泛,所以也沒有很好領會他的意思,答案也不是很準確,後來回去查了下資料,大概明白面試官要問的東西是什麼(尷尬,才反應過來),然後,也特地簡單總結下java記憶體溢出的相關內容,以備之後複習。

一、什麼情況下會java記憶體泄露?

  java不是有GC嗎?為毛還會記憶體泄露?之前我也一直以為,java有記憶體回收行程在,估計記憶體泄露的情況一般不會發生吧?後來發現並非如此,先看以下代碼:

//記憶體泄露的簡單例子//首先,要明白,GC它回收的是不可到達的對象,但是,在static 的集合類中,引用可以到達,但是卻有可能對象已經不用了//首先定義一個靜態變數public static ArrayList<Object> list = new ArrayList<Object>();public void stackOverExam(Object object){//當非靜態變數被static變數持有引用的時候,容易發生記憶體泄露,因為object是一直被list引用著的list.add(object);object = null;//這裡設定為null並沒有達到釋放object引用對應對象的效果,畢竟list還是持有引用}

 通過上面的代碼,估計大家也可以看到:由於static指向的對象是不能被記憶體回收行程回收的,所以,間接地object也無法回收,當業務對象很大而且很多時,便有記憶體泄露的風險了,所以我們可以總結到如下規則:當全域的靜態變數持有局部變數(或者說,大範圍的變數持有小範圍變數而且小範圍變數消耗記憶體較大、數目較多時),程式便有記憶體泄露的風險,一般來說,類似的例子還有,單例模式中的對象,模組之間的調用,內部類的引用被持有等

二、如何解決?

  經過百度一番,其實發覺解決的思路大概和下面這方面的知識有關:java的對象引用有以下幾類:強引用,軟引用,弱引用。具體看

解決剛說的記憶體泄露問題,主要運用的就是顯式聲明引用的類型,首先簡單解釋下相關的知識:

 1、引用的類型:強,軟,弱。普通的java引用,也是我們最一般的java引用對象,便是強引用,它直接影響記憶體回收的進行(有強引用指向對應的對象,GC便不可回收該對象,即使記憶體不夠用);軟引用,和強引用的主要區別是:它會影響GC對對象的回收工作,但是,當虛擬機器的記憶體不夠用時,軟引用所指向對象(當然,不能同時有強引用指向對象)會被強制回收;弱引用就等級更低,它無法影響GC對對象的記憶體回收工作,只能引用並訪問對象。具體三種引用可以由下面的代碼例子說明:

//軟引用和弱引用的使用例子public void referenceExam(){Object object  = new Object();//這個普通object引用就是一個強引用//軟引用通過SoftReference建立一個軟引用SoftReference<Object> softObjReference = new SoftReference<Object>(object);//通過get方法擷取真正的對象引用softObjReference.get();//弱引用通過WeakReference來關聯一個對象WeakReference<Object> weakObjReference = new WeakReference<Object>(object);weakObjReference.get();//這個方法返回了真實的對象引用,當沒有強引用或者弱引用指向它時,返回為null}

  

 2、對於防止記憶體泄露以及與記憶體回收有關的引用強弱類型,我們可以歸納出下面的特點:

    A、當我們在快取中緩衝較大的對象例如緩衝圖片等以提高讀取速度的時候(針對大記憶體對象問題),可以將相關的對象設定為軟引用對象,這樣保證在記憶體不夠用的時候GC可以進行回收工作。

     B、當我們完全不像由於當前對對象的引用而影響對象的其他模組原來設定的GC回收時期,我們可以採用弱引用(相當於只可訪問資料而訪問不會對GC對對象的回收造成影響)

    C、當然,java還有一種叫做虛引用的參考型別變數,該變數其實現實中用得不多,主要用來跟蹤對象GC過程,所以這裡不詳細講。

 

最後,至於什麼時候要設定對象為弱引用(或者軟引用),個人覺得還是要根據具體的業務進行對象使用的判斷,如果全域對象過大,有可能在程式中造成泄露問題,或者說我們不想在不清楚對象何時可以被回收(工廠通過介面提供對象給客戶)時,可以採用軟引用或者弱引用進行對象訪問。

當然,其實記憶體泄露是個很大的主題,這裡僅僅是討論了一小部分內容而已,各位有更多的見解也歡迎交流!

關於java記憶體泄露的總結--引用的類型:強引用,弱引用,軟引用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.