




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java 理論與實踐: JVM 1.4.1 中的垃圾收集 內容: 舊物件和新物件 分代收集(Generational Collection) JDK 1.4.1 預設收集器 微調垃圾收集器 結語 參考資料 關於作者 對本文的評價 相關內容: Java 理論與實踐 系列 Mash that trash - Incremental compaction in the IBM JDK Garbage Collector Sensible sanitation - Understanding the IBM Java Garbage Collector, Part 1: Object allocation IBM Developer Kits for the Java platform (downloads) 訂閱: dW 技術電子報 分代及並行垃圾收集Brian Goetz首席顧問, Quiotix Corp2003 年 12 月 01 日在上月的 Java 理論與實踐 中,專欄作家 Brian Goetz 回顧了垃圾收集的基本演算法。本月,他進一步探討 JVM 1.4.1 是如何實際處理 Garbage Collection ,包括一些新的針對多處理器系統 的 Garbage Collection 。請在本文 論壇 上與作者及其它讀者分享您對本文的心得(您也可以按下文章頂部或底部的討論 進入此論壇)。上個月,我們分析了參照計數(Reference Counting)、複製(Copying)、標籤-清除(mark-sweep)和標籤-整理(mark-compact)這些經典的 Garbage Collection 技術。其中每一種方法在特定條件下都有其優點和缺點。例如,當有很多物件成為垃圾時,複製可以做得很好,但是有許多長久物件時它就變得很糟(要反覆複製它們)。相反,標籤-整理對於長久物件可以做得很好(只複製一次),但是當有許多短暫物件時就沒有那麼好了。JVM 1.2 及以後版本使用的技術稱為分代垃圾收集(generational garbage collection),它結合這兩種技術的優點,讓物件指派的負擔變小。舊物件和新物件在任何一個應用程式Heap 中,一些物件在建立後很快就成為垃圾,另一些則在程式的整個執行期間一直保持生存。經驗分析表 示,對於大多數物件導向語言,包括 Java ,絕大多數物件 可以多達 98%(這取決於您對新物件的衡量標準)是在年輕的時候死亡的。可以用小時鐘秒數、物件指派以後記憶體管理子系統指派的總位元組或者物件指派後經歷的 Garbage Collection 次數來計算物件的壽命。但是不管您如何計算,分析顯示一件事 大多數物件是在年輕的時候死亡的。大多數物件在年輕時死亡這一事實對於收集器的選擇很有意義。特別是,當大多數物件在年輕時死亡時,複製收集器可以執行得相當好,因為複製收集器完全不存取死亡的物件,它們只是將活的物件複製到另一個Heap 欄位中,然後一次收回所有的剩餘空間。那些經歷過第一次 Garbage Collection 後仍能生存的物件,大部分會成為長久的或者永久的物件。根據短暫物件和長久物件的混合比例,不同 Garbage Collection 策略的效能會有非常大的差別。當大多數物件在年輕時死亡時,複製收集器可以 執行得很好,因為年輕時死亡的物件永遠不需要複製。不過,複製收集器處理長久物件卻很糟糕,它要從一個半空間向另一個半空間反覆來回複製這些物件。相反,標籤-整理收集器對於 長久物件可以工作得很好,因為長久物件趨向於沉在 Heap 的底部,因此不用再複製。不過,標籤-清除 和 標籤-理整 收集器要做很多額外的分析死亡物件的工作,因為在清除階段它們必須分析 Heap 中的每一個物件。分代收集(Generational Collection)分代收集器將 Heap 分為多個世代。在新世代中建立的物件,滿足某些提升標準的物件,如經歷了特定次數 Garbage Collection 的物件,將被提升到下一更舊的世代。 分代收集器對不同的世代可以自由使用不同的收集策略,對各世代分別進行 Garbage Collection。次要收集 (Minor Collection)分代收集的一個優點是它不同時收集所有的世代,因此可以使 Garbage Collection 暫停更短。當指派器不能滿足指派請求時,它首先觸發一個要收集(minor collection),它只收集最新的世代。因為新世代中的許多物件已經死亡,複製收集器完全不用分析死亡的物件,所以次要收集的暫停可以相當短並通常可以回收大量的 Heap 空間。如果次要收集釋放了足夠的 Heap 空間,那麼使用者程式就可以立即恢復。如果它不能釋放足夠的 Heap 空間,那麼它就繼續收集上一世代,直到回收了足夠的記憶體。(在 Garbage Collection 進行了全部收集以後仍不能回收足夠的記憶體時,它將擴充Heap 或者拋出 OutOfMemoryError)。兩代之間的參照追蹤垃圾收集器(garbage collector),如複製、標籤-清除和標籤-整理等垃圾收集器,都是從根集(Root set)開始掃瞄,巡訪物件間的參照,直到存取所有活的物件。分代追蹤收集器從根集開始,但是並不巡訪指向更舊一代中物件的參照,這減少了要追蹤物件的範圍。但是這也帶來一個問題 如果一個在舊世代中的物件參照到一個不能透過從根開始的所有參照鏈結到的新物件該怎麼辦?為了解決這個問題,分代收集器必須明確地追蹤從舊物件到新物件的參照並將這些舊到新的參照加入到次要收集的根集(Root set)中。有兩種建立從舊物件到新物件的參照的方法。要麼是將舊物件中包含的參照修改為指向新物件,要麼是將參照其它新物件的新物件提升為更舊的一代。追蹤兩代之間的參照不管一個舊到新的參照是透過提升還是指標修改建立的, 垃圾收集器在進行次要收集時需要有全部舊到新的參照。做到這一點的一種方法是追蹤舊世代,但是這顯然有很大的負擔。更好的一種方法是線性掃瞄舊世代以尋找對 新物件的參照。這種方法比追蹤更快並有更好的區域性(locality),但是仍然有很大的工作量。賦值函式(mutator)和垃圾收集器可以共同工作以在建立舊到新的參照時維護它們的完整清單。當物件提升為舊世代時,垃圾收集器可以記錄所有由於這種提升而建立的舊到新的參照,這樣就只需要追蹤由指標修改所建立的兩代之間的參照。垃圾收集器可以有幾種方法追蹤由修改現有物件中的參照而產生的舊到新的參照。它可以使用在參照計數收集器中維護參照計數的同樣方法(編譯器可以產生圍繞指標賦值的附加指令)追蹤它們,也可以在舊一代 Heap 上使用虛擬記憶體保護以捕捉對舊物件的寫入。另一種可能更有效的虛擬記憶體方法是在舊一代 Heap 中使用Page修改記號(Page modification dirty bit),以確定為找到包括舊到新指標的物件時要掃瞄的區塊。用一點小技巧,就可以避免追蹤每一個指標修改並檢查它是否跨越世代邊界的負擔。例如,不需要追蹤針對本地或者靜態變數的儲存,因為它們已經是根集的一部分了。也可以避免追蹤儲存在某些 建構函式中的指標,這些建構函式只用於初始化新增物件的欄位(即所謂初始化儲存(initializing stores),因為(幾乎)所有物件都是指派到新世代中。不管是什麼情況,執行庫都必須維護一個舊物件到新物件的參照集並在收集新世代時將這些參照新增到根集中。在圖 1 中,箭頭表示 Heap 中物件間的參照。紅色箭頭表示必須新增到根集中供次要收集使用的舊到新的參照。藍色箭頭表示從根集或者新世代到舊物件的參照,在只收集新世代時不需要追蹤它們。圖 1. 兩代之間的參照 卡片標籤Sun JDK 使用一種稱為 卡片標記(card marking)演算法的改進演算法以識別對舊一代物件的欄位中包括的指標的修改。在這種方法中,Heap 分為一組 卡片,每個卡片一般都小於一個記憶體分頁。JVM 維護著一個卡片對應,對應於Heap 中的每一個卡片都有一位元(在某些實作中是一個位元組)。每次修改Heap 中物件的指標欄位時,就在卡片對應中設定對應那張卡片的適當位元。在 Garbage Collection 時,對舊世代中卡片相關聯的標籤位元進行檢查,對不好的卡片掃瞄以尋找對新世代有參照的物件。然後清除標籤位元。卡片標籤有幾項負擔 卡片對應所需的額外空間、對每一個指標儲存所做的額外工作,以及在 Garbage Collection 時做的額外工作。對每一個非初始化Heap 指標儲存,卡片標籤演算法可以只增加兩到三個機器指令,並要求在次要收集時對所有不好卡片上的物件進行掃瞄。JDK 1.4.1 預設收集器在預設情況下,JDK 1.4.1 將 Heap 分為兩部分,一個新世代和一個舊世代(實際上,還有第三部分 永久空間,它用於儲存載入類別和方法物件)。借助於複製收集器,新的世代又分為一個建立空間(通常稱為 Eden)和兩個生存半空間。舊世代使用標籤-整理收集器。物件在經歷了幾次複製後提升到舊世代。次要收集將活的物件從 Eden 和一個生存半空間複製到另一個生存半空間,並可能提升一些物件到舊世代。主要的收集(major collection)既會收集新世代,也會收集舊的世代。System.gc() 方法總是觸發一個主要的收集,這就是應該儘量少用(如果不能完全不用的話)System.gc() 的原因之一,因為主要的收集要比次要收集花費長得多的時間。沒有辦法以程式化方式觸發次要收集。其它收集選擇除了預設情況下使用的複製收集器和標籤-整理收集器,JDK 1.4.1 還包括其它四種 Garbage Collection 演算法,每一種適用於不同的目的。JDK 1.4.1 包括一個增量收集器(incremental collector ,自 JDK 1.2 就已經出現了)和三種在多處理器系統中進行更有效收集的新收集器 平行複製收集器、平行清除(scavenging)收集器和並行標籤-清除收集器。這些新收集器是為了解決在多處理器系統中垃圾收集器成為瓶頸的問題。圖 2 顯示在什麼時候選擇備用收集的說明。圖 2. 1.4.1 選擇 Garbage Collection (Folgmann IT-Consulting 提供) 增量收集 (Incremental collection)增量收集自 1.2 起就成為 JDK 的一部分。增量收集減少了 Garbage Collection 暫停,以犧牲處理能力為代價,這使它只有在更短的收集暫停非常重要時才值得考慮,如接近 Realtime 系統。Train 演算法是 JDK 用於增量收集的演算法,它在舊世代和新世代之間建立一個新欄位。這些Heap 欄位劃分為火車(train),每個火車又分為一系列的車廂(car)。每個車廂可以分別收集。結果,每個火車車廂組成單獨的一世代,這意味著不但要追蹤舊到新的參照,而且還要追蹤從舊火車到新火車以及舊車廂到新車廂的參照。這為賦值函式(mutator)和垃圾收集器帶來了大量的額外工作,但是可以得到更短的收集暫停。平行收集器和並行收集器JDK 1.4.1 中新的收集器都是為解決多處理器系統中垃圾收集器的問題而設計的。因為大多數 Garbage Collection 演算法會在一段時間裡使系統停止,單執行緒的收集器很快會成為延展瓶頸,因為在垃圾收集器將使用者程式執行緒 暫止時,除了一個處理器之外,其它的處理器都是空閒的。新收集器中的兩個平行複製收集器和並行標籤-清除收集器設計為減少收集暫停時間。另一個是平行清除收集器,它是為在大Heap 上的更高處理能力而設計的。平行複製收集器用 JVM -XX:+UseParNewGC 選項啟用,是一個新世代複製收集器,它將 Garbage Collection 的工作分為與 CPU 數量一樣多的執行緒。並行標籤-清除收集器由 -XX:+UseConcMarkSweepGC 選項啟用,它是一個舊世代標籤-清除收集器,它在初始標籤階段(及在以後暫短重新標籤階段)暫短地停止整個系統,然後恢復使用者程式,同時垃圾收集器執行緒與使用者程式並行地執行。平行複製收集器和並行標籤-清除收集器基本上是預設的複製收集器和標籤-整理收集器的並行版本。由 -XX:+UseParallelGC 啟用的平行清除收集器是新世代收集器,針對多處理器系統上非常大(Gigabyte 以及更大的)Heap 進行了最佳化。選擇一種演算法有六種演算法可以選擇,您可能不知道要使用哪一種。圖 2 提供了一些指引,將收集器分為單執行緒和並行的,以及分為短暫停和高處理能力的。只要您掌握了應用程式和佈署環境的資訊,就足以選擇合適的演算法。對於許多應用程式,預設的收集器可以 運作得很好因此如果您沒有效能問題,那麼就沒必要加入更多的複雜性。不過,如果您的應用程式是佈署在多處理器系統上或者使用非常大的 Heap ,那麼改變收集器選項可能會有巨大的效能提升。 微調垃圾收集器JDK 1.4.1 還包括大量的微調 Garbage Collection 的選項。調整這些選項並衡量它們的效果可能會花費您大量時間,因此在試圖微調垃圾收集器之前先對您的應用程式進行徹底的組態(profile)和最佳化,這樣您的微調工作可能會得到
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 小学学生安全培训心得课件
- 2025内蒙古鄂尔多斯市呼和浩特站引才选聘考前自测高频考点模拟试题附答案详解(考试直接用)
- IKK-16-Standard-生命科学试剂-MCE
- HS-20093-Antibody-GSK5764227-生命科学试剂-MCE
- 租赁合同委托范本6篇
- 2025吉林长春兴隆综合保税区投资建设集团有限公司招聘模拟试卷及答案详解参考
- Gln4-Neurotensin-生命科学试剂-MCE
- 小学体育安全知识培训课件
- 医疗大数据行业前景展望
- 农民合作小区农业生产管理服务协议
- 2.3河流与湖泊第1课时课件-八年级地理上学期人教版
- 专题04 利用基本不等式求最值(压轴题8大类型专项训练)数学人教A版2019必修一(解析版)
- 2025上海浦东新区浦东公安分局文员招聘300人考试参考题库及答案解析
- 2025年三方股权合作合同协议书
- 工程结算审核工作方案(3篇)
- 地方病竞赛试题及答案
- 弘扬伟大抗战精神为实现中华民族伟大复兴而奋斗2025-2026学年高二上学期爱国主义教育主题班会
- 秋季企业施工安全培训内容课件
- DBJT15-147-2018 建筑智能工程施工、检测与验收规范
- 高血压防治知识课件下载
- HG∕T 3792-2014 交联型氟树脂涂料
评论
0/150
提交评论