Java垃圾回收器的工作原理


上課,老師照本宣科,實在難以理解,干脆就看書包里的Java書,正好看了Java的垃圾回收器是如何工作的,覺得有必要記錄一下。

參考於 Java編程思想第四版(Thinking in Java)

  老年代中一般使用標記壓縮 

  新生代中一般使用copy,所以有一個eden和兩個survivor。

1.垃圾回收器對於提高對象的創建速度,有明顯的效果

  問題來了,垃圾回收是釋放對象,而關創建對象什么事?

  首先了解一下Java是如何在堆上分配內存的,Java使用“堆指針”每分配一個對象,指針就往后移一位,類似於堆棧,這樣就達到了高速創建對象,但這樣的方法帶來了弊端,在堆棧中還可以出棧來釋放,在堆里你沒有出棧啊,不一會堆(內存)就滿了,就要放磁盤上去,非常浪費時間。那么這時候垃圾回收裝置就介入了,他幫助我們回收空間,並處理因為釋放對象而產生的碎片(因為有的對象可能比較小,釋放后就空了一塊內存,比如大小為5,但是其他對象的大小都在10以上,那么這塊內存就是碎片了,別的對象根本就放不進去)。

  有了垃圾回收器,所以java才能使用“堆指針”來創建對象,所以說垃圾回收器對創建速度有明顯的效果 

2.Java垃圾回收器的具體機制

  2.1 引用計數法

    就是每個對象都有一個標志,每次被引用1次就加1,如果引用為0,那么就會去回收,但會有特殊情況,如果兩個對象在堆里,互相引用,那么使用這種方法就失效了,所以java中不用這種方法。

  2.2停止-復制(stop-and-copy)  和  標記-清掃(mark-and-sweep)

    這兩個思想是相同的,不同具體實現略有不同。這兩種方式需要程序暫停才能工作

    首先從堆棧或靜態存儲區開始,遍歷所有的引用,根據引用找到對象,再遍歷查看找到對象中的引用,依次下去,這樣就避免的互相引用的問題,因為如果互相引用,那么在堆棧中根本就不會出現

    停止-復制就是在開辟一個堆,然后把“活”的引用復制到堆中,不過開辟堆實在太浪費,感覺就在把一個堆划分成不同的塊,在塊中復制。

    標記-清掃就是“活”的對象給個標記,先找出打好標記,然后在回收。

    Java虛擬機可以自適應切換兩種方法,因為如果在很少需要回收的對象時,如果還使用停止-復制未免也太浪費了,如果一直用標記-清掃,那么就會產生很多的碎片,有很多碎片的時候就用停止-復制,因為復制到另一個塊中,程序自然會去把對象排列好。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM