以前看過很多次關于垃圾回收相關的文章,都只是看過就忘記了,沒有好好的整理一下,發(fā)現(xiàn)寫文章可以強化自己的記憶。
java與C,c++有很大的不同就是java語言開發(fā)者不需要關注內(nèi)存信息,不會顯式的直接操作內(nèi)存,而是通過jvm虛擬機來實現(xiàn)。 java虛擬機運行的時候內(nèi)存分配圖如下圖:
jvm虛擬機棧:一個是線程獨有的,每次啟動一個線程,就創(chuàng)建一個jvm虛擬機棧,線程退出的時候就銷毀。這里面主要保存線程本地變量名和局部變量值。 本地方法棧: 調(diào)用本地jni方法的時候而創(chuàng)建的。這里分配的jvm之外的內(nèi)存空間。方法調(diào)用結束之后銷毀。 pc寄存器 : 這個保存線程當前執(zhí)行的字節(jié)碼指令 堆:主要保存創(chuàng)建的對象。 方法區(qū):保存class相關的信息。主要是class的一個內(nèi)存結構信息 常量池:方法區(qū)的一部分,主要保存class內(nèi)存結構中常量值 例如String值,public static final 類型的值
我們這里說的垃圾回收,主要是java虛擬機對堆內(nèi)存區(qū)域的回收。
1 首先的問題是:jvm如何知道那些對象需要回收 ?目前有兩種算法
在root搜索算法的里面,我們說的引用這里都指定的是強引用關系。所謂強引用關系,就是通過用new 方式創(chuàng)建的對象,并且顯示關聯(lián)的對象
以上就是代表的是強引用關系,變量obj 強引用了 Object的一個對象。 java里面有四種應用關系,從強到弱分別為: Strong Reference(強引用) –>Weak Reference (弱引用) -> Soft Reference(軟引用) – > Phantom Reference(引用)
Strong Reference : 只有在引用對象root不可達的情況下才會標識為可回收,垃圾回收才可能進行回收 Weak Reference :即使在root算法中 其引用的對象root可達到,但是如果jvm堆內(nèi)存 不夠的時候,還是會被回收。 Soft Reference : 無論其引用的對象是否root可達,在響應內(nèi)存需要時,由垃圾回收判斷是否需要回收。 Phantom Reference :在回收器確定其指示對象可另外回收之后,被加入垃圾回收隊列.
下面可以看一個測試
這里創(chuàng)建大約1000個 10K的 Weak Reference 對象,最后打印的結果是:被回收的對象數(shù):767,這里ReferenceObject如果設置為1K的話,最后的打印結果是0 這個例子并不嚴謹,但是卻說明了被Weak Reference的對象在一定的時候會被jvm回收,但是強引用就不會出現(xiàn)這種狀態(tài)。 |
|