版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> How a garbage collector works</p><p> If you come from a programming language where allocating objects on the heap is expensive, you may naturally assume that Java’s scheme of allocating everythi
2、ng (except primitives) on the heap is also expensive. However, it turns out that the garbage collector can have a significant impact on increasing the speed of object creation. This might sound a bit odd at first—that st
3、orage release affects storage allocation—but it’s the way some JVMs work, and it means that allocating storage for heap obj</p><p> For example, you can think of the C++ heap as a yard where each object sta
4、kes out its own piece of turf. This real estate can become abandoned sometime later and must be reused. In some JVMs, the Java heap is quite different; it’s more like a conveyor belt that moves forward every time you all
5、ocate a new object. This means that object storage allocation is remarkably rapid. The “heap pointer” is simply moved forward into virgin territory, so it’s effectively the same as C++’s stack allocation. (</p>&l
6、t;p> Now you might observe that the heap isn’t in fact a conveyor belt, and if you treat it that way, you’ll eventually start paging memory a lot (which is a big performance hit) and later run out. The trick is that
7、the garbage collector steps in, and while it collects the garbage it compacts all the objects in the heap so that you’ve effectively moved the “heap pointer” closer to the beginning of the conveyor belt and farther away
8、from a page fault. The garbage collector rearranges things and makes </p><p> To understand how this works, you need to get a little better idea of the way different garbage collector (GC) schemes work. A s
9、imple but slow garbage collection technique is is called reference counting. This means that each object contains a reference counter, and every time a reference is attached to an object, the reference count is increased
10、. Every time a reference goes out of scope or is set to null, the reference count is decreased. Thus, managing reference counts is a small but constant </p><p> In faster schemes, garbage collection is not
11、based on reference counting. Instead, it is based on the idea that any nondead object must ultimately be traceable back to a reference that lives either on the stack or in static storage. The chain might go through sever
12、al layers of objects. Thus, if you start in the stack and the static storage area and walk through all the references, you’ll find all the live objects. For each reference that you find, you must trace into the object th
13、at it points to</p><p> In the approach described here, the JVM uses an adaptive garbage-collection scheme, and what it does with the live objects that it locates depends on the variant currently being used
14、. One of these variants is stop-and-copy. This means that—for reasons that will become apparent—the program is first stopped (this is not a background collection scheme). Then, each live object that is found is copied fr
15、om one heap to another, leaving behind all the garbage. In addition, as the objects are copied int</p><p> Of course, when an object is moved from one place to another, all references that point at (i.e., t
16、hat reference) the object must be changed. The reference that goes from the heap or the static storage area to the object can be changed right away, but there can be other references pointing to this object that will be
17、encountered later during the “walk.” These are fixed up as they are found (you could imagine a table that maps old addresses to new ones). </p><p> There are two issues that make these so-called “copy colle
18、ctors” inefficient. The first is the idea that you have two heaps and you slosh all the memory back and forth between these two separate heaps, maintaining twice as much memory as you actually need. Some JVMs deal with t
19、his by allocating the heap in chunks as needed and simply copying from one chunk to another. </p><p> The second issue is the copying. Once your program becomes stable, it might be generating little or no g
20、arbage. Despite that, a copy collector will still copy all the memory from one place to another, which is wasteful. To prevent this, some JVMs detect that no new garbage is being generated and switch to a different schem
21、e (this is the “adaptive” part). This other scheme is called mark-and-sweep, and it’s what earlier versions of Sun’s JVM used all the time. For general use, mark-and-sweep is f</p><p> Mark-and-sweep follow
22、s the same logic of starting from the stack and static storage and tracing through all the references to find live objects. However, each time it finds a live object, that object is marked by setting a flag in it, but th
23、e object isn’t collected yet. Only when the marking process is finished does the sweep occur. During the sweep, the dead objects are released. However, no copying happens, so if the collector chooses to compact a fragmen
24、ted heap, it does so by shuffling objec</p><p> The “stop-and-copy” refers to the idea that this type of garbage collection is not done in the background; instead, the program is stopped while the garbage c
25、ollection occurs. In the Sun literature you’ll find many references to garbage collection as a low-priority background process, but it turns out that the garbage collection was not implemented that way, at least in earli
26、er versions of the Sun JVM. Instead, the Sun garbage collector ran when memory got low. In addition, mark-and-sweep requir</p><p> As previously mentioned, in the JVM described here memory is allocated in b
27、ig blocks. If you allocate a large object, it gets its own block. Strict stop-and-copy requires copying every live object from the source heap to a new heap before you could free the old one, which translates to lots of
28、memory. With blocks, the garbage collection can typically copy objects to dead blocks as it collects. Each block has a generation count to keep track of whether it’s alive. In the normal case, only the blo</p><
29、;p> There are a number of additional speedups possible in a JVM. An especially important one involves the operation of the loader and what is called a just-in-time (JIT) compiler. A JIT compiler partially or fully co
30、nverts a program into native machine code so that it doesn’t need to be interpreted by the JVM and thus runs much faster. When a class must be loaded (typically, the first time you want to create an object of that class)
31、, the .class file is located, and the byte codes for that class are </p><p> 垃圾收集器的工作方式</p><p> 如果你學(xué)下過(guò)一種因?yàn)樵诙牙锓峙鋵?duì)象所以開銷過(guò)大的編程語(yǔ)言,很自然你可能會(huì)假定Java 在堆里為每一樣?xùn)|西(除了 primitives)分配內(nèi)存資源的機(jī)制開銷也會(huì)很大。 不過(guò),事實(shí)上垃圾收集器能
32、夠深刻影響對(duì)象的加速創(chuàng)建。 一開始聽起來(lái)有些奇怪——存貯空間的釋放會(huì)影響存貯空間的分配,但是這的確是一些 JVMs 的工作方式,并且這意味著 Java 為堆對(duì)象分配存貯空間幾乎和別的語(yǔ)言里為棧分配存貯空間一樣地快.</p><p> 舉個(gè)例子,你可以認(rèn)為 C++的堆就如同一個(gè)堆放的工場(chǎng),在這個(gè)工場(chǎng)里,每一個(gè)對(duì)象都立樁為界。 對(duì)象切實(shí)擁有的地皮占有權(quán)不久會(huì)被廢除無(wú)效,并且這塊地皮必須重新加以利用。 在Java 的
33、 JVM 里,堆的工作方式完全不同;每次為一個(gè)新的對(duì)象分配存貯空間的時(shí)候,它就更像是一個(gè)不斷向前移動(dòng)的傳送帶。 這就意味著對(duì)象存貯空間的分配速度明顯加快。 在這個(gè)過(guò)程中,“堆指針”簡(jiǎn)單地向還沒被占用的空間領(lǐng)域移動(dòng),所以非常像 C++里棧的分配方式。 (當(dāng)然,記錄工作會(huì)有一點(diǎn)額外的開銷,但是完全不同于 C++里那種在堆放工場(chǎng)里為尋找沒被利用的存貯空間而付出的開銷。)</p><p> 你或許觀察到實(shí)際上堆本身并不
34、是一個(gè)傳送帶,如果你真的那樣看待堆,你就會(huì)啟用虛擬內(nèi)存——在硬盤里不斷地裝卸,結(jié)果是看上去你會(huì)擁有比實(shí)際情況還要多的內(nèi)存空間。 最終當(dāng)你創(chuàng)建了足夠多的對(duì)象后,你會(huì)耗盡內(nèi)存。 Java 的訣竅就在于垃圾搜集器插手于其中,當(dāng)垃圾收集器收集垃圾的時(shí)候,它會(huì)壓縮所有堆里的對(duì)象以便你能夠有效的將堆指針移動(dòng)到離傳送帶更近的地方從而遠(yuǎn)離了頁(yè)面錯(cuò)誤。垃圾收集器重新安排了整個(gè)過(guò)程,這使得分配存貯空間的時(shí)候一種高速,無(wú)窮閑置的堆模式成為可能。</p&
35、gt;<p> 要想理解 Java 的垃圾收集工作,先了解一下別的語(yǔ)言系統(tǒng)里垃圾收集所使用的方案是有幫助的。一種簡(jiǎn)單的但卻較慢的垃圾收集技術(shù)就是引用記數(shù)(refrence counting).這種技術(shù)意味著每個(gè)對(duì)象都含有一個(gè)引用計(jì)數(shù)器,每一次一個(gè)引用指向那個(gè)對(duì)象的時(shí)候,引用記數(shù)就增加一 每一次對(duì)象引用離開作用域或者被設(shè)置為 null 的時(shí)候,引用記數(shù)就減一。 因此,應(yīng)付對(duì)象被引用的數(shù)量在你的程序的整個(gè)生命周期里是一筆
36、較小但卻一直持續(xù)的開銷?;占鳉v遍整組對(duì)象,當(dāng)它發(fā)現(xiàn)一個(gè)引用記數(shù)為零的對(duì)象時(shí)就會(huì)釋放那個(gè)對(duì)象的存貯空間。(不過(guò),只要記數(shù)為零,引用記數(shù)方案通常會(huì)立刻釋放對(duì)象)。 這種方案的一個(gè)缺點(diǎn)是如果對(duì)象之間循環(huán)著互相引用,那么這些對(duì)象的引用記數(shù)可能為非零,而垃圾收集器依然把它們當(dāng)作垃圾收集。 定位這種自我引用的對(duì)象組需要垃圾收集器付出大量額外的工作。 引用記數(shù)通常被用來(lái)解釋一類垃圾收集的工作原理,但是它似乎沒被任何一種 JVM 所采納。基礎(chǔ)上。&
37、lt;/p><p> 有一種執(zhí)行更快的垃圾收集方案,這種方案中垃圾收集不是建立在引用記數(shù)的基礎(chǔ)上。相反,它的思想是是任何沒死的對(duì)象最終一定會(huì)在棧和靜態(tài)存貯器里找到相應(yīng)存活的引用。 這種鏈?zhǔn)降牟檎曳绞娇赡軞v遍幾個(gè)層次的對(duì)象組。 因此,如果從棧和靜態(tài)存貯器里開始并歷遍整個(gè)引用組,你會(huì)找到所有存活的對(duì)象。 對(duì)于你找到的每個(gè)單引用,你必須找到它所指向的對(duì)象,然后發(fā)覺那個(gè)對(duì)象的所有引用,接著找到那些引用所指向的所有對(duì)象,依次
38、類推,直到你歷遍整個(gè)由棧和靜態(tài)存貯器里的引用所形成的網(wǎng)。 每個(gè)你找到的對(duì)象必須還存活著。 注意,這里不存在分離的自我引用的對(duì)象組——他們只是沒被查找到,因此被自動(dòng)當(dāng)作垃圾。</p><p> 在上述提到的垃圾收集方案中,JVM 使用了一種自適應(yīng)的垃圾收集方案,它對(duì)查找到活對(duì)象采取的措施依賴于它正在使用的方案變體。 其中的一個(gè)變體就是 stop-and-copy。 它意味著——基于一些明顯的原因——程序首先停止運(yùn)
39、行(這不是一種在后臺(tái)實(shí)施的垃圾收集方案)。 然后,每一個(gè)活著的對(duì)象從一個(gè)堆里被拷貝到另一個(gè)堆里,同時(shí)被拷貝的活對(duì)象和死的對(duì)象被當(dāng)作垃圾遺棄。 并且,當(dāng)對(duì)象被拷貝到新的堆里后,他們?cè)谀抢锉灰粋€(gè)挨一個(gè)塞緊,因此實(shí)現(xiàn)了壓縮新堆的目的(而且如前所述,這種方式騰出了壓縮后多余出來(lái)的新的空間)。</p><p> 當(dāng)然,對(duì)象從一個(gè)地方移動(dòng)到另一個(gè)地方的時(shí)候,所有指向?qū)ο蟮囊帽仨毾鄳?yīng)改變。 指向堆或者靜態(tài)存貯器里某個(gè)被移動(dòng)
40、對(duì)象的引用可以立即得到改變,但是還存在其它后來(lái)“在走走”的時(shí)候才會(huì)碰到的指向該對(duì)象的引用。 這些引用一旦發(fā)現(xiàn)就會(huì)被修改。(你可以想象存在一張映射舊新地址的表)。</p><p> 有兩個(gè)問題使這種所謂的 “拷貝型收集器”缺乏效率。 第一個(gè)問題就是你使用了兩個(gè)堆,為了維護(hù)兩倍于你實(shí)際所需要的內(nèi)存空間,你得在這兩個(gè)堆之間來(lái)回?cái)噭?dòng)著整個(gè)內(nèi)存空間。 一些 JVMs 通過(guò)依據(jù)實(shí)際所需來(lái)為堆分配大塊內(nèi)存,然后很簡(jiǎn)單地從一個(gè)
41、塊拷貝對(duì)象到另一個(gè)塊。</p><p> 第二個(gè)問題是拷貝過(guò)程本身。 一旦你地程序趨向于穩(wěn)定的時(shí)候,它可能生成很少或者幾乎不生成垃圾。 然而 stop-and-copy 方案不管這些,拷貝型垃圾收集器依舊把活對(duì)象占用的空間從一個(gè)地方拷貝到另一個(gè)地方,這就形成了浪費(fèi)。 為了阻止這種情況的發(fā)生,一些 JVMs會(huì)探測(cè)沒有新垃圾產(chǎn)生的時(shí)機(jī),并且會(huì)轉(zhuǎn)向?qū)嵤┝硗庖粋€(gè)完全不同的垃圾收集方案。 這種不同的方案被稱為 mark-
42、and-sweep,并且它是 Sun 的早期 JVM 版本一直使用的方案。 處理一般的垃圾收集工作,mark-and-sweep 表現(xiàn)得相當(dāng)?shù)芈?,但是?dāng)你的程序生成很少或者不生成垃圾時(shí),它又運(yùn)行得很快。</p><p> Mark-and-sweep 遵循著和 stop-and-copy 一樣的邏輯:從棧和靜態(tài)存貯器里出發(fā),跟蹤所有的引用從而找到存活的對(duì)象。 不過(guò),每次它找到活對(duì)象的時(shí)候,那個(gè)對(duì)象被做以標(biāo)記,而
43、且對(duì)象還不會(huì)被收集起來(lái)。 只有在整個(gè)標(biāo)記過(guò)程完成后,清掃(sweep)工作才真正開始。在清掃過(guò)程中,死對(duì)象被釋放存貯空間。 不過(guò),Mark-and-sweep 方案的實(shí)施過(guò)程并沒有拷貝壓縮的步驟發(fā)生,所以如果垃圾收集器打算壓縮已經(jīng)成為碎片的堆,它會(huì)采用如同洗牌一樣的方式來(lái)重新安排對(duì)象的散亂分布。</p><p> stop-and-copy 的思想是垃圾收始工作。 在 Sun 的文獻(xiàn)資料里,你會(huì)發(fā)現(xiàn)很多資料認(rèn)為
44、垃圾收集是一種低優(yōu)先性的后臺(tái)進(jìn)程,但事實(shí)上垃圾收集在早期的 Sun JVM 版本里并不是這樣執(zhí)行地。 相反,當(dāng)內(nèi)存閑置空間少的時(shí)候,Sun 的垃圾收集器會(huì)終止程序運(yùn)行。 Mark-and-sweep 也需要程序被終止。 正如前面提到的,在這里描述的 JVM 里,內(nèi)存被分配成大的塊。 如果你指定了一個(gè)大的對(duì)象,它將會(huì)得到它自己的內(nèi)存塊。 嚴(yán)格意義上的stop-and-copy 在可以釋放舊堆之前,需要從源堆里拷貝每一個(gè)活著的對(duì)象到新的堆里
45、,這會(huì)耗費(fèi)大量?jī)?nèi)存。 而有了塊的概念,垃圾收集器在收集的時(shí)候就能夠拷貝對(duì)象到死的塊里。每一個(gè)塊都有一個(gè)生成數(shù)用來(lái)跟蹤它是否還活著。正常情況下,只有自上次垃圾收集后創(chuàng)建的塊才被壓縮;所有別的塊如果在什么地方被引用著的話,相應(yīng)的生成記數(shù)會(huì)增加。 這種方式解決了通常情況下許多短期生存的暫時(shí)對(duì)象。徹底的清掃工作會(huì)周期性進(jìn)行?!髮?duì)象仍舊不拷貝(他們只是把自己的生成記數(shù)增加),而那些包含小對(duì)象的塊會(huì)被拷貝和壓縮。 JVM 會(huì)監(jiān)視垃圾收集的效率,
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 畢業(yè)設(shè)計(jì)外文文獻(xiàn)翻譯---java垃圾收集器的工作方式
- 液體收集器
- 散裝物料收集器的設(shè)計(jì)
- qq號(hào)碼收集器教程
- qq號(hào)碼收集器教程
- 旋轉(zhuǎn)編碼器工作方式圖解
- 垃圾收集器中大對(duì)象管理及顯式內(nèi)存管理的研究.pdf
- 壓電能量收集器的研究.pdf
- 康復(fù)醫(yī)學(xué)的工作方式
- 睡前童話故事:時(shí)間收集器
- 手扶式落葉收集器論文.doc
- 集群信息收集器的設(shè)計(jì)研究.pdf
- 睡前童話故事:時(shí)間收集器
- 螺旋式散裝物料收集器的設(shè)計(jì)
- 網(wǎng)絡(luò)數(shù)據(jù)發(fā)生及收集器的研究.pdf
- 螺旋式散裝物料收集器的設(shè)計(jì)
- 淺談低碳工作方式
- 螺旋式散裝物料收集器設(shè)計(jì)
- 水浴恒溫振蕩器工作方式及特點(diǎn)
- 螺旋式散裝物料收集器的設(shè)計(jì)
評(píng)論
0/150
提交評(píng)論