Java中會存在記憶體流失嗎__Java

來源:互聯網
上載者:User


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

Java記憶體管理機制

在C++ 語言中,如果需要動態分配一塊記憶體,程式員需要負責這塊記憶體的整個生命週期。從申請分配、到使用、再到最後的釋放。這樣的過程非常靈活,但是卻十分繁瑣,程式員很容易由於疏忽而忘記釋放記憶體,從而導致記憶體的泄露。 Java 語言對記憶體管理做了自己的最佳化,這就是記憶體回收機制。 Java 的幾乎所有記憶體對象都是在堆記憶體上分配(基礎資料型別 (Elementary Data Type)除外),然後由 GC ( garbage collection)負責自動回收不再使用的記憶體。

上面是Java 記憶體管理機制的基本情況。但是如果僅僅理解到這裡,我們在實際的項目開發中仍然會遇到記憶體流失的問題。也許有人表示懷疑,既然 Java 的記憶體回收機制能夠自動的回收記憶體,怎麼還會出現記憶體流失的情況呢。這個問題,我們需要知道 GC 在什麼時候回收記憶體對象,什麼樣的記憶體對象會被 GC 認為是“不再使用”的。

Java中對記憶體對象的訪問,使用的是引用的方式。在 Java 代碼中我們維護一個記憶體對象的引用變數,通過這個引用變數的值,我們可以訪問到對應的記憶體位址中的記憶體對象空間。在 Java 程式中,這個引用變數本身既可以存放堆記憶體中,又可以放在代碼棧的記憶體中(與基礎資料型別 (Elementary Data Type)相同)。 GC 線程會從代碼棧中的引用變數開始跟蹤,從而判定哪些記憶體是正在使用的。如果 GC 線程通過這種方式,無法跟蹤到某一塊堆記憶體,那麼 GC 就認為這塊記憶體將不再使用了(因為代碼中已經無法訪問這塊記憶體了)。

通過這種有向圖的記憶體管理方式,當一個記憶體對象失去了所有的引用之後,GC 就可以將其回收。反過來說,如果這個對象還存在引用,那麼它將不會被 GC 回收,哪怕是 JAVA 虛擬機器拋出 OutOfMemoryError 。 Java記憶體泄露 一般來說記憶體流失有兩種情況。一種情況 如在C/C++ 語言中的,在堆中的分配的記憶體,在沒有將其釋放掉的時候,就將所有能訪問這塊記憶體的方式都刪掉(如指標重新賦值) ;另一種情況則是 在記憶體對象明明已經不需要的時候,還仍然保留著這塊 記憶體 和它的 訪問方式 (引用) 。第一種情況,在 Java 中已經由於記憶體回收機制的引入,得到了很好的解決。所以, Java 中的記憶體流失,主要指的是第二種情況。    可能光說概念太抽象了,大家可以看一下這樣的例子:

Vector v = new  Vector( 10 );  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 程式發生了記憶體流失

System.out.println("vector.get(0)==="+vector.get(0)); 

儘管對於C/C++ 中的記憶體泄露情況來說, Java 記憶體泄露導致的破壞性小,除了少數情況會出現程式崩潰的情況外,大多數情況下程式仍然能正常運行。但是,在行動裝置對於記憶體和 CPU都有較嚴格的限制的情況下, Java 的記憶體溢出會導致程式效率低下、佔用大量不需要的記憶體等問題。這將導致整個機器效能變差,嚴重的也會引起拋出 OutOfMemoryError ,導致程式崩潰。


java 的記憶體回收機制:

1.記憶體回收是由虛擬機器自動執行,不能人為地幹預。
       2.系統比較空閑(記憶體回收線程)
       3.對象不在被引用.對象處於引用的隔離島狀態(隔離引用),對象具備了回收的條件
       4.gc()方法,可以建議虛擬機器執行記憶體回收,但是不能確定是否會執行回收。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.