2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

java 垃圾回收總結(1)

 小豬窩969 2015-09-09

以前看過很多次關于垃圾回收相關的文章,都只是看過就忘記了,沒有好好的整理一下,發(fā)現(xiàn)寫文章可以強化自己的記憶。


 


java與C,c++有很大的不同就是java語言開發(fā)者不需要關注內(nèi)存信息,不會顯式的直接操作內(nèi)存,而是通過jvm虛擬機來實現(xiàn)。


java虛擬機運行的時候內(nèi)存分配圖如下圖:


1


 


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如何知道那些對象需要回收 ?


目前有兩種算法



  • 引用計數(shù)法



每個對象上都有一個引用計數(shù),對象每被引用一次,引用計數(shù)器就+1,對象引用被釋放,引用計數(shù)器-1,直到對象的引用計數(shù)為0,對象就標識可以回收


這個可以用數(shù)據(jù)算法中的圖形表示,對象A-對象B-對象C 都有引用,所以不會被回收,對象B由于沒有被引用,沒有路徑可以達到對象B,對象B的引用計數(shù)就就是0,對象B就會被回收。


 


 2




但是這個算法有明顯的缺陷,對于循環(huán)引用的情況下,循環(huán)引用的對象就不會被回收。例如下圖:對象A,對象B 循環(huán)引用,沒有其他的對象引用A和B,則A和B 都不會被回收。


 3




  • root搜索算法



這種算法目前定義了幾個root,也就是這幾個對象是jvm虛擬機不會被回收的對象,所以這些對象引用的對象都是在使用中的對象,這些對象未使用的對象就是即將要被回收的對象。簡單就是說:如果對象能夠達到root,就不會被回收,如果對象不能夠達到root,就會被回收。




如下圖:對象D訪問不到根對象,所以就會被回收


4




以下對象會被認為是root對象:



  • 被啟動類(bootstrap加載器)加載的類和創(chuàng)建的對象

  • jvm運行時方法區(qū)類靜態(tài)變量(static)引用的對象

  • jvm運行時方法去常量池引用的對象

  • jvm當前運行線程中的虛擬機棧變量表引用的對象

  • 本地方法棧中(jni)引用的對象




由于這種算法即使存在互相引用的對象,但如果這兩個對象無法訪問到根對象,還是會被回收。如下圖:對象C和對象D互相引用,但是由于無法訪問根,所以會被回收。


5




jvm在確定是否回收的對象的時候采用的是root搜索算法來實現(xiàn)。



在root搜索算法的里面,我們說的引用這里都指定的是強引用關系。所謂強引用關系,就是通過用new 方式創(chuàng)建的對象,并且顯示關聯(lián)的對象


1
Object obj = new Object();

以上就是代表的是強引用關系,變量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 :在回收器確定其指示對象可另外回收之后,被加入垃圾回收隊列.


 


下面可以看一個測試


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class ReferenceTest {
    public static final Map<Integer, Reference> map = new HashMap<Integer, Reference>();
    public static void main(String[] args) {
        for (int i = 0; i < 1000; i++) {
            map.put(i, new WeakReference(new ReferenceObject(i)));
        }
        int i = 0;
        for (Reference r : map.values()) {
            if (r.get() == null) {
                i++;
            }
        }
        System.out.println("被回收的對象數(shù):" + i);
    }
    static class ReferenceObject {
        private int    i;
        private byte[] b;
        public ReferenceObject(int i) {
            this.i = i;
            b = new byte[1024 *10];
        }
    }
}

這里創(chuàng)建大約1000個 10K的 Weak Reference 對象,最后打印的結果是:被回收的對象數(shù):767,這里ReferenceObject如果設置為1K的話,最后的打印結果是0


這個例子并不嚴謹,但是卻說明了被Weak Reference的對象在一定的時候會被jvm回收,但是強引用就不會出現(xiàn)這種狀態(tài)。

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多