當前位置:
首頁 > 知識 > Java垃圾回收

Java垃圾回收

垃圾回收機制的作用:

Java語言中一個顯著的特點就是引入了垃圾回收機制,使c++程序員最頭疼的內存管理的問題迎刃而解,它使得Java程序員在編寫程序的時候不再需要考慮內存管理。由於有個垃圾回收機制,Java中的對象不再有「作用域」的概念,只有對象的引用才有「作用域」。垃圾回收可以有效的防止內存泄露,有效的使用空閑的內存。

ps:內存泄露是指該內存空間使用完畢之後未回收,在不涉及複雜數據結構的一般情況下,Java 的內存泄露表現為一個內存對象的生命周期超出了程序需要它的時間長度,我們有時也將其稱為「對象游離」。

觸發GC的條件:

JVM進行次GC的頻率很高,但因為這種GC佔用時間極短,所以對系統產生的影響不大。更值得關注的是主GC的觸發條件,因為它對系統影響很明顯。總的來說,有兩個條件會觸發主GC:

1)當應用程序空閑時,即沒有應用線程在運行時,GC會被調用。因為GC在優先順序最低的線程中進行,所以當應用忙時,GC線程就不會被調用,但以下條件除外。

2)Java堆內存不足時,GC會被調用。當應用線程在運行,並在運行過程中創建新對象,若這時內存空間不足,JVM就會強制地調用GC線程,以便回收內存用於新的分配。若GC一次之後仍不能滿足內存分配的要求,JVM會再進行兩次GC作進一步的嘗試,若仍無法滿足要求,則 JVM將報「out of memory」的錯誤,Java應用將停止。

由於是否進行主GC由JVM根據系統環境決定,而系統環境在不斷的變化當中,所以主GC的運行具有不確定性,無法預計它何時必然出現,但可以確定的是對一個長期運行的應用來說,其主GC是反覆進行的

減少GC開銷的幾種方法:

根據上述GC的機制,程序的運行會直接影響系統環境的變化,從而影響GC的觸發。若不針對GC的特點進行設計和編碼,就會出現內存駐留等一系列負面影響。為了避免這些影響,基本的原則就是儘可能地減少垃圾和減少GC過程中的開銷。具體措施包括以下幾個方面:

(1)不要顯式調用System.gc()

此函數建議JVM進行主GC,雖然只是建議而非一定,但很多情況下它會觸發主GC,從而增加主GC的頻率,也即增加了間歇性停頓的次數。

(2)盡量減少臨時對象的使用

臨時對象在跳出函數調用後,會成為垃圾,少用臨時變數就相當於減少了垃圾的產生,從而延長了出現上述第二個觸發條件出現的時間,減少了主GC的機會。

(3)對象不用時最好顯式置為Null

一般而言,為Null的對象都會被作為垃圾處理,所以將不用的對象顯式地設為Null,有利於GC收集器判定垃圾,從而提高了GC的效率。

(4)盡量使用StringBuffer,而不用String來累加字元串

由於String是固定長的字元串對象,累加String對象時,並非在一個String對象中擴增,而是重新創建新的String對象,如Str5=Str1+Str2+Str3+Str4,這條語句執行過程中會產生多個垃圾對象,因為對次作「+」操作時都必須創建新的String對象,但這些過渡對象對系統來說是沒有實際意義的,只會增加更多的垃圾。避免這種情況可以改用StringBuffer來累加字元串,因StringBuffer是可變長的,它在原有基礎上進行擴增,不會產生中間對象。

(5)能用基本類型如Int,Long,就不用Integer,Long對象

基本類型變數佔用的內存資源比相應對象佔用的少得多,如果沒有必要,最好使用基本變數。

(6)盡量少用靜態對象變數

靜態變數屬於全局變數,不會被GC回收,它們會一直佔用內存。

(7)分散對象創建或刪除的時間

集中在短時間內大量創建新對象,特別是大對象,會導致突然需要大量內存,JVM在面臨這種情況時,只能進行主GC,以回收內存或整合內存碎片,從而增加主GC的頻率。集中刪除對象,道理也是一樣的。它使得突然出現了大量的垃圾對象,空閑空間必然減少,從而大大增加了下一次創建新對象時強制主GC的機會

垃圾回收的幾種演算法:

Java語言規範沒有明確地說明JVM使用哪種垃圾回收演算法,但是任何一種垃圾回收演算法一般要做2件基本的事情:(1)發現無用信息對象;(2)回收被無用對象佔用的內存空間,使該空間可被程序再次使用。

大多數垃圾回收演算法使用了根集(root set)這個概念;所謂根集就是正在執行的Java程序可以訪問的引用變數的集合(包括局部變數、參數、類變數),程序可以使用引用變數訪問對象的屬性和調用對象的方法。垃圾回收首先需要確定從根開始哪些是可達的和哪些是不可達的,從根集可達的對象都是活動對象,它們不能作為垃圾被回收,這也包括從根集間接可達的對象。而根集通過任意路徑不可達的對象符合垃圾收集的條件,應該被回收。下面介紹幾個常用的演算法。

2.1. 引用計數法(Reference Counting Collector)

引用計數法是唯一沒有使用根集的垃圾回收的法,該演算法使用引用計數器來區分存活對象和不再使用的對象。一般來說,堆中的每個對象對應一個引用計數器。當每一次創建一個對象並賦給一個變數時,引用計數器置為1。當對象被賦給任意變數時,引用計數器每次加1當對象出了作用域後(該對象丟棄不再使用),引用計數器減1,一旦引用計數器為0,對象就滿足了垃圾收集的條件。

基於引用計數器的垃圾收集器運行較快,不會長時間中斷程序執行,適宜地必須實時運行的程序。但引用計數器增加了程序執行的開銷,因為每次對象賦給新的變數,計數器加1,而每次現有對象出了作用域生,計數器減1。

2.2. tracing演算法(Tracing Collector)

tracing演算法是為了解決引用計數法的問題而提出,它使用了根集的概念。基於tracing演算法的垃圾收集器從根集開始掃描,識別出哪些對象可達,哪些對象不可達,並用某種方式標記可達對象,例如對每個可達對象設置一個或多個位。在掃描識別過程中,基於tracing演算法的垃圾收集也稱為標記和清除(mark-and-sweep)垃圾收集器.

2.3. compacting演算法(Compacting Collector)

為了解決堆碎片問題,基於tracing的垃圾回收吸收了Compacting演算法的思想,在清除的過程中,演算法將所有的對象移到堆的一端,堆的另一端就變成了一個相鄰的空閑內存區,收集器會對它移動的所有對象的所有引用進行更新,使得這些引用在新的位置能識別原來的對象。在基於Compacting演算法的收集器的實現中,一般增加句柄和句柄表。

2.4. copying演算法(Coping Collector)

該演算法的提出是為了克服句柄的開銷和解決堆碎片的垃圾回收。它開始時把堆分成一個對象區和多個空閑區,程序從對象區為對象分配空間,當對象滿了,基於coping演算法的垃圾回收就從根集中掃描活動對象,並將每個活動對象複製到空閑區(使得活動對象所佔的內存之間沒有空閑間隔),這樣空閑區變成了對象區,原來的對象區變成了空閑區,程序會在新的對象區中分配內存。

一種典型的基於coping演算法的垃圾回收是stop-and-copy演算法,它將堆分成對象區和空閑區域區,在對象區與空閑區域的切換過程中,程序暫停執行。

2.5. generation演算法(Generational Collector)

stop-and-copy垃圾收集器的一個缺陷是收集器必須複製所有的活動對象,這增加了程序等待時間,這是coping演算法低效的原因。在程序設計中有這樣的規律:多數對象存在的時間比較短,少數的存在時間比較長。因此,generation演算法將堆分成兩個或多個,每個子堆作為對象的一代 (generation)。由於多數對象存在的時間比較短,隨著程序丟棄不使用的對象,垃圾收集器將從最年輕的子堆中收集這些對象。在分代式的垃圾收集器運行後,上次運行存活下來的對象移到下一最高代的子堆中,由於老一代的子堆不會經常被回收,因而節省了時間。

2.6. adaptive演算法(Adaptive Collector)

在特定的情況下,一些垃圾收集演算法會優於其它演算法。基於Adaptive演算法的垃圾收集器就是監控當前堆的使用情況,並將選擇適當演算法的垃圾收集器

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 笑月天狼 的精彩文章:

TAG:笑月天狼 |

您可能感興趣

垃圾女孩有一本Junk Journal
Python 和 Ruby 的分代垃圾回收機制
很多Gmail用戶都收到了垃圾郵件
iMessage垃圾簡訊沒停過,蘋果回應
iPhone日常破事之:iMessage垃圾信息又回來泛濫了
為什麼Holochain是垃圾
Apple 正在努力減少中國的 iMessage 垃圾郵件
警惕!國內iPhone用戶正在面臨大量iMessage垃圾信息
國內iPhone用戶正在面臨大量iMessage垃圾
微軟 Visual Studio C+Runtime 安裝程序是失效的、垃圾的
垃圾郵件活動濫用SettingContent-ms傳播FlawedAmmyy RAT
微軟對電子垃圾回收商的入獄判決做出回應:「他在偽造Windows軟體。」
Linux之父Linus Torvalds惡評Intel漏洞修復補丁:完全是個垃圾
McAfee報告:全球97%的垃圾郵件皆來自Necurs和Gamut殭屍網路
撿垃圾之633的iPhone se
Plogging運動(一起去慢跑撿垃圾吧)
蘋果回應iMessage簡訊問題:正在探索辦法減少垃圾信息
蘋果有意使用AI來攔截iMessage垃圾信息
沃爾沃推出新型全電動「垃圾運輸」車;Google Research 升級為 Google AI
adidas 創造了一雙「垃圾」?