1. 程式人生 > >淺談java垃圾回收(一)

淺談java垃圾回收(一)

本文簡述java垃圾回收機制自己的一點理解,希望能對java學習的朋友有一點幫助,謝謝;

先了解下JVM:

JVM百度百科詳情https://baike.so.com/doc/1063579-1125177.html

JVM是Java Virtual Machine(Java虛擬機器)的縮寫,JVM是一種用於計算裝置的規範,它是一個虛構出來的計算機,是通過在實際的計算機上模擬模擬各種計算機功能來實現的。

 

1.什麼是java的垃圾回收

java GC百度百科地址(https://baike.so.com/doc/9559973-9904818.html

 垃圾回收—GC(Garbage Collection),JAVA特有功能,垃圾收集意味著程式不再需要的物件是"無用資訊",這些資訊將被丟棄,在大多時候這些被丟棄的資訊,java會自動回收;它與“java面向程式設計”一樣是java語言的特性之一;它與“ c/c++語言”最大區別是不用手動呼叫 free()  和 delete() 釋放記憶體。GC 主要是處理 Java堆Heap ,也就是作用在 Java虛擬機器 用於存放物件例項的記憶體區域,(Java堆又稱為GC堆)。JVM能夠完成記憶體分配和記憶體回收,雖然降低了開發難度,避免了像C/C++直接操作記憶體的危險。但也正因為太過於依賴JVM去完成記憶體管理,導致很多Java開發者不再關心記憶體分配,導致很多程式低效、耗記憶體問題。因此開發者需要主動了解GC機制,充分利用有限的記憶體的程式,才能寫出更高效的程式。

2.垃圾回收的特點

總結為一下幾點:

1.自動回收機制,JVM會判斷一段程式是不是有用,在無用的情況下該段程式會有一定的記憶體消耗,而JVM的垃圾回收機制會在判斷完成之後自動釋放該程式碼佔用的記憶體,以確保程式的高效執行;

2.垃圾收集能自動釋放記憶體空間,減輕程式設計的負擔,提高程式設計效率;

3.自動回收記憶體碎片(碎片是分配給物件的記憶體塊之間的空閒記憶體洞);

4.垃圾收集的開銷影響程式效能(JVM會追蹤執行程式中有用的物件,可能程式會執行很長時間,他會一直追蹤直到程式終止無用,再進行記憶體回收;還有就是垃圾回收的演算法存在一定的問題);

 

3.GC演算法

職能:

(1)發現無用資訊物件;(檢測垃圾

(2)回收被無用物件佔用的記憶體空間,使該空間可被程式再次使用。(回收垃圾

GC演算法有好多,下邊列舉幾個常用的作對比:

方法名稱 特點
引用計數法 1.佔用資源:因為每個物件都需要維護一個計數器,每次指標有更新都伴隨著計數器的更新,一定程度上佔用了計算資源 
2.佔用記憶體:計數器需要佔用一定的記憶體,為了安全起見,計數器值的上限要大於所有物件的上限,這也是一筆不小的開銷 
3.實現複雜,無法解決迴圈計數
標記清除演算法 1.演算法簡單,實現簡單 
2.碎片化:由於只是將垃圾物件清除掉,對於存活物件不做處理,所以由於存活物件分佈的不連續性,會導致可用記憶體被分割成一塊塊的。
3.與寫時複製技術不相容:寫時複製(Copy On Write)是一個很重要的思想,可以優化記憶體佔用或者提升併發環境下的效能。
複製演算法

1.效率快:相比於標記清除演算法,複製演算法在標記階段,只需要標記哪些物件是活動的就可以了,相比於標記清除演算法需要遍歷所有的物件,效能上有提升

2.不會發生碎片化:同樣相比於標記清除演算法,由於存活下來的物件會在To區中連續的分配,因此不會像標記清除演算法那樣,需要維護碎片空間

3.分配速度快:由於不會發生碎片化,如果有一個新的物件請求記憶體,那麼分配時可以直接追加在From區已用記憶體之後,分配的速度快

4.記憶體使用率低:由於複製演算法把記憶體分成了兩塊,那麼對於物件的可用空間來說,僅僅是其他演算法的一半

5.自物件的遞迴複製:一個物件通常會關聯一些自物件。在複製這些物件的時候,還需要遞迴的去處理它的自物件,這通常會產生一定的開銷。同時,在遞迴呼叫時,存在著函式棧的消耗,潛藏著棧溢位的風險

分代收集演算法 分堆回收,新老交換,回收效率高
自適應演算法 監控堆,選擇適當的垃圾回收器

4.常用垃圾回收器

垃圾回收器有很多,本文不做一一贅述,下邊主要介紹Serial收集器、  ParallelScavenge收集器、CMS收集器;

1.Serial收集器(序列回收器)

JDK1.3之前廣泛使用這個收集器,目前也是ClientVM下 ServerVM 4核4GB以下機器的預設垃圾回收器。序列收集器並不是只能使用一個CPU進行收集,而是當JVM需要進行垃圾回收的時候,需要中斷所有的使用者執行緒,知道它回收結束為止,因此又號稱“Stop The World” 的垃圾回收器。注意,JVM中文名稱為java虛擬機器,因此它就像一臺虛擬的電腦一樣在工作,而其中的每一個執行緒就被認為是JVM的一個處理器,因此大家看到圖中的CPU0、CPU1實際為使用者的執行緒,而不是真正機器的CPU。

2.  ParallelScavenge收集器(吞吐量優先的收集器)

所提到的吞吐量=程式執行時間/(JVM執行回收的時間+程式執行時間),假設程式運行了100分鐘,JVM的垃圾回收佔用1分鐘,那麼吞吐量就是99%。在當今網路告訴發達的今天,良好的響應速度是提升使用者體驗的一個重要指標,多核並行雲端計算的發展要求程式儘可能的使用CPU和記憶體資源,儘快的計算出最終結果,因此在互動不多的雲端,比較適合使用該回收器。

3.CMS收集器

CMS又稱響應時間優先(最短回收停頓)的回收器,使用併發模式回收垃圾,使用標記-清除演算法,CMS對CPU是非常敏感的,它的回收執行緒數=(CPU+3)/4,因此CPU核心數越多,GC回收時佔用CPU資源率越低;

CMS模式主要分為四個過程

初始標記(CMS initial mark)

併發標記(CMS concurrent mark)

重新標記(CMS remark)

併發清除(CMS concurrent sweep)

在初始標記的時候,需要中斷所有使用者執行緒,在併發標記階段,使用者執行緒和標記執行緒

併發執行,而在這個過程中,隨著記憶體引用關係的變化,可能會發生原來標記的物件被釋放,進而引發新的垃圾,因此可能會產生一系列的浮動垃圾,不能被回收,浮動垃圾過多也可能導致回收失敗。

5.JVM怎麼判斷物件可以回收了

1,物件沒有引用

2,作用域發生未捕獲異常

3,程式在作用域正常執行完畢

4,程式執行了System.exit()

5,程式發生意外終止(被殺程序等)

java 垃圾回收本次就先這麼多,下次繼續談!!!

本人才疏學淺,文中如出現不對的地方請在評論區指出,謝謝!!!

原創不易,轉載時請註明出處,謝謝!!!