垃圾回收(GC)是JVM的一大殺器,它使程序員可以更高效地專注于程序的開發(fā)設(shè)計,而不用過多地考慮對象的創(chuàng)建銷毀等操作。但是這并不是說程序員不需要了解GC。GC只是Java編程中一項自動化工具,任何一個工具都有它適用的范圍,當(dāng)超出它的范圍的時候,可能它將不是那么自動,而是需要人工去了解與適應(yīng)地適用。
擁有一定工作年限的程序員,在工作期間肯定會經(jīng)常碰到像內(nèi)存溢出、內(nèi)存泄露、高并發(fā)的場景。這時候在應(yīng)對這些問題或場景時,如果對GC不了解,很可能會成為個人的發(fā)展瓶頸。
接下來的兩文將詳細(xì)學(xué)習(xí)下JVM中垃圾回收(GC)的各個知識要點。本文先從GC的算法開始先了解,鋪墊好基礎(chǔ),下一篇再詳細(xì)講JVM具體的GC實現(xiàn)。
GC對象搜索算法垃圾回收,第一件事就是要搞清楚哪些東西是垃圾,而后才能對這些垃圾進(jìn)行回收。
那么有什么辦法識別對象是否為無用的垃圾呢?狹義地,怎么判斷對象是否沒被引用呢?
通常有以下兩種算法去識別判斷
引用計數(shù)算法
這個算法非常簡單。給對象一個計數(shù)器,每當(dāng)這個對象被引用了,計數(shù)器值加一;引用失效,則減一。但這個對象計數(shù)值為0的時候,證明是無用對象,可以被GC程序回收掉。這種算法比較廣泛應(yīng)用在一些腳本語言上,如FLASH、PYTHON等。
但是引用計數(shù)算法無法解決對象間相互引用的問題。當(dāng)a對象引用了b對象,b對象也引用了a對象,這樣a、b兩個對象的計數(shù)器值都不會為0,即使這兩個對象都被其他對象所引用,最終導(dǎo)致這些對象一直無法被回收。這種情況往往會出現(xiàn)在比較復(fù)雜的編程語言中。
可達(dá)性分析算法
可達(dá)性分析算法(GC roots算法),廣泛應(yīng)用于主流的商用語言。設(shè)置一個根節(jié)點,從圖論角度來看,只要從該節(jié)點可達(dá)一個對象,證明這個對象是存活的(被引用)。
通常地,GC會包含以下區(qū)域的對象:
虛擬機棧(棧幀中的本地變量表)中引用的對象;
方法區(qū)中類靜態(tài)屬性引用的對象;
方法區(qū)中常量引用的對象;
本地方法棧中JNI(即一般說的Native方法)引用的對象;
垃圾回收算法了解完垃圾是怎么找出來后,接下來看看它們是怎么被清除的。以下介紹幾種清除的算法。
標(biāo)記-清除算法(Mark-Sweep)標(biāo)記-清除,顧名思義,先標(biāo)記垃圾,再清除。它是GC最基礎(chǔ)的算法,后續(xù)很多算法都是基于它上面去改進(jìn)的。
標(biāo)記的過程在上面搜索GC對象已經(jīng)介紹過了。被標(biāo)記的對象,在統(tǒng)一GC的時候會把標(biāo)記的對象清除掉。這個算法比較簡單,不做過多贅述。
這個算法有一個很明顯的缺點,就是在垃圾回收后會產(chǎn)生大量不連續(xù)的碎片空間,導(dǎo)致程序要申請較大的對象時常無法找到合適的內(nèi)存空間,迫使再次GC。
復(fù)制算法的存在,正是為了解決內(nèi)存碎片問題。并且這個算法也是分代算法的基礎(chǔ)。
將內(nèi)存分為大小相等的兩塊,每次程序只使用其中一塊,當(dāng)GC發(fā)生的時候,把存活的對象復(fù)制到另外一塊內(nèi)存中,整齊的排列,然后清空原來的那塊內(nèi)存。
可以看到,這種算法有點新生代轉(zhuǎn)移到老年代的感覺。
缺點:
把內(nèi)存可使用的空間減少了一半,造成空間的浪費。
對象存活數(shù)量較多的時候,復(fù)制性能比較差
這種缺點,在老年代中,對象存活率比較高的場景下是非常場景間。
標(biāo)記-整理算法(Mark-Compact)針對復(fù)制算法的兩個缺點,在老年代一般會用這種標(biāo)記-整理算法。
把存活的對象移到內(nèi)存的一段,然后把剩余的空間全部清空掉。
分代算法并不是一個特定的算法,也沒有什么新的內(nèi)容。而是把內(nèi)存分成多個區(qū)域,一般為新生代、老年代等。然后根據(jù)不同區(qū)域不同的特點,用不同回收算法去回收垃圾。
例如新生代,對象存活率低,比較適用復(fù)制算法。老年代存活率高,比較適用Mark-Compact算法。
目前幾乎所有的商業(yè)虛擬機都是采用分代收集的。具體不同的收集器在下一文再詳細(xì)說明。
更多技術(shù)文章、精彩干貨,請關(guān)注
博客:zackku.com
微信公眾號:Zack說碼
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/77297.html
摘要:上,數(shù)據(jù)按有限大小的包傳輸,這些包成為數(shù)據(jù)報,每個數(shù)據(jù)報包含一個首部和一個有效載荷。不過,由于數(shù)據(jù)報長度有限,通常必須將數(shù)據(jù)分解為多個包,再在目的地重新組合。這兩個構(gòu)造函數(shù),在返回之前會與遠(yuǎn)程主機建立一個活動的網(wǎng)絡(luò)連接。 Internet上,數(shù)據(jù)按有限大小的包傳輸,這些包成為數(shù)據(jù)報(datagram),每個數(shù)據(jù)報包含一個首部(header)和一個有效載荷(payload)。首部包含包發(fā)...
摘要:歡迎來我的個人站點性能優(yōu)化其他優(yōu)化瀏覽器關(guān)鍵渲染路徑開啟性能優(yōu)化之旅高性能滾動及頁面渲染優(yōu)化理論寫法對壓縮率的影響唯快不破應(yīng)用的個優(yōu)化步驟進(jìn)階鵝廠大神用直出實現(xiàn)網(wǎng)頁瞬開緩存網(wǎng)頁性能管理詳解寫給后端程序員的緩存原理介紹年底補課緩存機制優(yōu)化動 歡迎來我的個人站點 性能優(yōu)化 其他 優(yōu)化瀏覽器關(guān)鍵渲染路徑 - 開啟性能優(yōu)化之旅 高性能滾動 scroll 及頁面渲染優(yōu)化 理論 | HTML寫法...
閱讀 3213·2021-11-02 14:44
閱讀 3725·2021-09-02 15:41
閱讀 1661·2019-08-29 16:57
閱讀 1784·2019-08-26 13:38
閱讀 3297·2019-08-23 18:13
閱讀 2104·2019-08-23 15:41
閱讀 1668·2019-08-23 14:24
閱讀 3029·2019-08-23 14:03