垃圾回收算法以及垃圾回收器_什么是垃圾回收?
垃圾回收算法以及垃圾回收器
以下是我們的垃圾收集手冊中的一個示例,該手冊將在接下來的幾周內(nèi)發(fā)布。 同時,花點時間熟悉垃圾收集的基礎(chǔ)知識-這將是本書的第一章。
乍一看,垃圾收集應(yīng)該處理顧名思義的問題–查找并丟棄垃圾。 實際上,它所做的恰恰相反。 垃圾收集正在跟蹤所有仍在使用的對象,并將其余對象標(biāo)記為垃圾。 牢記這一點,我們開始深入研究如何為Java虛擬機(jī)實現(xiàn)稱為“垃圾回收”的自動內(nèi)存回收過程。
手動內(nèi)存管理
在我們以現(xiàn)代形式開始介紹Garbage Collection之前,讓我們快速回顧一下過去,您不得不手動,顯式分配和釋放數(shù)據(jù)存儲空間。 而且,如果您忘記釋放它,則將無法重用該內(nèi)存。 該內(nèi)存將被聲明但未被使用。 這種情況稱為內(nèi)存泄漏 。
這是一個使用C語言編寫的,使用手動內(nèi)存管理的簡單示例:
int send_request() {size_t n = read_size();int *elements = malloc(n * sizeof(int));if(read_elements(n, elements) < n) {// elements not freed!return -1;}// …free(elements)return 0; }如我們所見,忘記釋放內(nèi)存是很容易的。 內(nèi)存泄漏曾經(jīng)是比現(xiàn)在更常見的問題。 您只能通過修復(fù)代碼來真正打敗他們。 因此,更好的方法將是自動回收未使用的內(nèi)存,從而完全消除人為錯誤的可能性。 這種自動化稱為垃圾收集 (或簡稱GC)。
智能指針
自動進(jìn)行垃圾收集的第一種方法是基于引用計數(shù)。 對于每個對象,您只知道它被引用了多少次,并且當(dāng)計數(shù)達(dá)到零時,就可以安全地回收該對象。 一個眾所周知的例子是C ++的共享指針:
int send_request() {size_t n = read_size();stared_ptr<vector<int>> elements = make_shared(new vector<int>());if(read_elements(n, elements) < n) {return -1;}return 0; }我們正在使用的shared_ptr會跟蹤對其的引用數(shù)。 此數(shù)字隨著您的傳遞而增加,隨著其離開范圍而減小。 一旦引用數(shù)量達(dá)到零, shared_ptr就會自動刪除基礎(chǔ)向量。
自動內(nèi)存管理
在上面的C ++代碼中,我們?nèi)匀槐仨毭鞔_地說出何時需要進(jìn)行內(nèi)存管理。 但是,如果我們可以使所有對象以這種方式表現(xiàn)呢? 這將非常方便,因為開發(fā)人員可能不再需要考慮自己清理。 運行時將自動了解不再使用某些內(nèi)存,并將其釋放。 換句話說,它會自動收集垃圾 。 1959年,第一個垃圾收集器出現(xiàn)在Lisp那里,從那時起,這項技術(shù)才發(fā)展起來。
參考計數(shù)
我們用C ++的共享指針演示的想法可以應(yīng)用于所有對象。 許多語言(例如Perl,Python或PHP)都采用這種方法。 最好用圖片來說明:
綠云表示程序員指向的對象仍在使用中。 從技術(shù)上講,這些可能是諸如當(dāng)前正在執(zhí)行的方法中的局部變量或靜態(tài)變量之類的東西。 它可能因編程語言而異,因此在此我們將不再關(guān)注。
藍(lán)色圓圈是內(nèi)存中的對象,您可以看到對其的引用數(shù)量。 最后,灰色圓圈是未從任何范圍引用的對象。 因此,灰色物體是垃圾,可以由垃圾收集器清理。
這一切看起來真的很好,不是嗎? 可以,但是整個方法都有很大的缺點。 結(jié)束對象的分離循環(huán)是很容易的,這些對象都不在范圍內(nèi),但是由于循環(huán)引用,其引用的計數(shù)不為零。 這是一個例子:
看到? 紅色對象實際上是應(yīng)用程序不使用的垃圾。 但是由于引用計數(shù)的限制,仍然存在內(nèi)存泄漏。
有一些方法可以克服此問題,例如使用特殊的“弱”引用或應(yīng)用單獨的算法來收集周期。 提到的語言(Perl,Python和PHP)都以一種或另一種方式處理循環(huán),但這超出了本手冊的范圍。 相反,我們將開始更詳細(xì)地研究JVM所采用的方法。
掃一掃
首先,JVM更具體地說明了對象的可訪問性。 與其在前幾章中看到的模糊定義的綠色云,不如我們有一組非常具體和明確的對象,稱為“ 垃圾收集根” :
- 局部變量
- 活動線程
- 靜態(tài)場
- JNI參考
- 其他(稍后將討論)
JVM用于跟蹤所有可到達(dá)(活動)對象并確保可重用非可訪問對象聲明的內(nèi)存的方法稱為標(biāo)記和清除算法。 它包括兩個步驟:
- 標(biāo)記正在遍歷所有可到達(dá)的對象,并將有關(guān)所有此類對象的分類帳保存在本機(jī)內(nèi)存中
- 掃描確保了不可訪問對象占用的內(nèi)存地址可以在下一次分配中重用。
JVM中的不同GC算法(例如Parallel Scavenge,Parallel Mark + Copy或CMS)在實現(xiàn)這些階段時略有不同,但是從概念上講,該過程仍然類似于上述兩個步驟。
關(guān)于此方法,至關(guān)重要的一點是周期不再泄漏:
不太好的事情是,需要停止應(yīng)用程序線程以進(jìn)行收集,因為如果引用線程一直在變化,那么您就無法真正計數(shù)它們。 當(dāng)應(yīng)用程序暫時停止以使JVM可以沉迷于家政活動時,這種情況稱為Stop The World暫停 。 它們的發(fā)生可能有多種原因,但是垃圾收集是迄今為止最受歡迎的一種。
如果您能夠通過發(fā)布獲得成功,那么我僅建議您訂閱我們的Twitter feed ,在其中繼續(xù)發(fā)布與Java性能相關(guān)的其他主題。
翻譯自: https://www.javacodegeeks.com/2015/05/what-is-garbage-collection.html
垃圾回收算法以及垃圾回收器
總結(jié)
以上是生活随笔為你收集整理的垃圾回收算法以及垃圾回收器_什么是垃圾回收?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 橙光游戏电脑版(橙光游戏电脑版网页)
- 下一篇: 手机上玩电脑网页游戏(手机玩电脑网页游戏