国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

Reference-持有引用簡析

2019-11-08 20:04:46
字體:
來源:轉載
供稿:網友

Reference是java.lang.ref包中的抽象類,主要作用為了包裝引用,為垃圾回收提供更大的靈活性,繼承Reference的類中有三個非常具有代表性,分別是SoftReference、WeakReference、PhantomReference。分別對應java虛擬機規范中的軟,弱、虛三種引用,可能我們平時用的比較少,大多數情況下,我們是直接new對象進行賦值,這屬于強引用,垃圾回收器并不會進行回收。 下面通過例子,它們分別如何應用,首先我們將設置jvm參數(eclipse中設置,不會的百度):-XX:+PRintGCDetails -XX:+PrintGCTimeStamps -Xms10m -Xmx10m。

public class SimpleJava{ static class Entry { public final int id; public final String type; public Entry(int id, String type) { this.id = id; this.type = type; } public final byte[] b = new byte[1024 * 1024 * 1]; @Override protected void finalize() throws Throwable { checkqueue(); System.out.println("對象最后回收前標記:" + this); } @Override public String toString() { return "id : " + id + ", type : " + type; } } private static void checkqueue() { Reference<? extends Entry> r = rq.poll(); if(r != null) { System.out.println("對象進入回收隊列:" + r.get()); checkqueue(); } } private static ReferenceQueue<Entry> rq = new ReferenceQueue<>(); public static void main(String[] args) { int size = 10; LinkedList<Reference<Entry>> list = new LinkedList<>(); for(int i = 0; i < size; i++) {// list.add(new WeakReference<>(new Entry(i, "Weak"), rq)); list.add(new SoftReference<>(new Entry(i, "soft"), rq));// list.add(new PhantomReference<>(new Entry(i, "Phantom"), rq)); System.out.println("元素:--" + list.getLast().get()); } }}

我們通過SoftReference對對象進行包裝,然后加入到list集合中,此時每個子項SoftReference就是屬于強引用,垃圾回收器并不會回收。 現在我們觀看打印結果。

元素:--id : 0, type : soft0.080: [GC [PSYoungGen: 1800K->488K(3072K)] 1800K->1656K(10240K), 0.0016371 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 元素:--id : 1, type : soft元素:--id : 2, type : soft0.082: [GC [PSYoungGen: 2674K->488K(3072K)] 3842K->3736K(10240K), 0.0015083 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 元素:--id : 3, type : soft元素:--id : 4, type : soft0.084: [GC [PSYoungGen: 2559K->504K(3072K)] 5807K->5816K(10240K), 0.0013574 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 0.086: [Full GC [PSYoungGen: 504K->0K(3072K)] [ParOldGen: 5312K->5660K(7168K)] 5816K->5660K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0108456 secs] [Times: user=0.11 sys=0.00, real=0.01 secs] 元素:--id : 5, type : soft元素:--id : 6, type : soft0.097: [Full GC [PSYoungGen: 2063K->1024K(3072K)] [ParOldGen: 5660K->6684K(7168K)] 7723K->7708K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0066311 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 元素:--id : 7, type : soft0.104: [Full GC [PSYoungGen: 2058K->2048K(3072K)] [ParOldGen: 6684K->6684K(7168K)] 8742K->8732K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0045077 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 0.108: [Full GC [PSYoungGen: 2048K->2048K(3072K)] [ParOldGen: 6684K->6673K(7168K)] 8732K->8721K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0075998 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 對象進入回收隊列:nullException in thread "main" 對象進入回收隊列:null對象進入回收隊列:null對象進入回收隊列:null對象進入回收隊列:null對象進入回收隊列:null對象進入回收隊列:null對象進入回收隊列:null對象最后回收前標記:id : 1, type : soft對象最后回收前標記:id : 0, type : soft對象最后回收前標記:id : 3, type : soft對象最后回收前標記:id : 2, type : soft對象最后回收前標記:id : 5, type : soft對象最后回收前標記:id : 4, type : soft對象最后回收前標記:id : 7, type : soft對象最后回收前標記:id : 6, type : softjava.lang.OutOfMemoryError: Java heap space at com.esy.rice.tool.simple.SimpleJava$Entry.<init>(SimpleJava.java:21) at com.esy.rice.tool.simple.SimpleJava.main(SimpleJava.java:48)

當最后堆內存不足時,系統進行gc,但任然不能進行內存的回收,此時finalize方法進行執行,并且在引用隊列中有Reference對象,但是其中包裝的對象卻不能取出。這是怎么一回事呢? 先簡單描述下垃圾回收的幾個階段,首先是對象判活,進行對象可達性分析,之后將不可達的對象進行F-Queue中,然后調用對象的finalize方法,此時對象最后能夠自救的方法(需要this指向方法外的引用),最后gc才會將確定不可達的對象進行回收。 從上面的打印中可以看出,ReferenceQueue正是Reference包裝的對象進行回收的隊列,打印的信息同樣也印證了垃圾回收的幾個過程,但是上面我們都是強調gc會回收不可達的對象。我們程序中并沒有不可達的對象啊,似乎都是強引用。而這就是SoftReference的特性,由其進行包裝的類,當內存即將溢出的時候,gc會進行回收動作,我們程序中報錯是因為gc是需要時間的,這個時間比內存分配慢了些。 從SoftReference這個特性我們可以看出,SoftReference非常適合內存敏感的高速緩存。 當我們把程序中new SoftReference<>(new Entry(i, “soft”), rq)進行注釋,換成new WeakReference<>(new Entry(i, “Weak”), rq)。 看下面打印:

元素:--id : 0, type : Weak0.077: [GC [PSYoungGen: 1800K->504K(3072K)] 1800K->1640K(10240K), 0.0018023 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 元素:--id : 1, type : Weak元素:--id : 2, type : Weak對象進入回收隊列:null0.080: [GC [PSYoungGen: 2690K->504K(3072K)] 3826K->3740K(10240K), 0.0021215 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 元素:--id : 3, type : Weak對象最后回收前標記:id : 0, type : Weak元素:--id : 4, type : Weak0.083: [GC [PSYoungGen: 2601K->504K(3072K)] 5838K->5820K(10240K), 0.0017948 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 0.085: [Full GC [PSYoungGen: 504K->0K(3072K)] [ParOldGen: 5316K->4636K(7168K)] 5820K->4636K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0095411 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 對象進入回收隊列:null對象進入回收隊列:null元素:--id : 5, type : Weak對象進入回收隊列:null元素:--id : 6, type : Weak0.095: [GC [PSYoungGen: 2081K->128K(3072K)] 6718K->6812K(10240K), 0.0016162 secs] [Times: user=0.01 sys=0.00, real=0.00 secs] 0.097: [Full GC [PSYoungGen: 128K->0K(3072K)] [ParOldGen: 6684K->6685K(7168K)] 6812K->6685K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0094562 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 對象進入回收隊列:null元素:--id : 7, type : Weak對象進入回收隊列:null對象進入回收隊列:null元素:--id : 8, type : Weak0.107: [Full GC [PSYoungGen: 2069K->2048K(3072K)] [ParOldGen: 6685K->6685K(7168K)] 8755K->8733K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0039976 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 0.111: [Full GC [PSYoungGen: 2048K->2048K(3072K)] [ParOldGen: 6685K->6674K(7168K)] 8733K->8722K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0086574 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] 對象最后回收前標記:id : 2, type : Weak對象進入回收隊列:null對象進入回收隊列:null對象最后回收前標記:id : 8, type : Weak對象最后回收前標記:id : 7, type : WeakException in thread "main" 對象最后回收前標記:id : 6, type : Weak對象最后回收前標記:id : 5, type : Weak對象最后回收前標記:id : 4, type : Weak對象最后回收前標記:id : 3, type : Weak對象最后回收前標記:id : 1, type : Weakjava.lang.OutOfMemoryError: Java heap space at com.esy.rice.tool.simple.SimpleJava$Entry.<init>(SimpleJava.java:21) at com.esy.rice.tool.simple.SimpleJava.main(SimpleJava.java:47)

發現和SoftReference引用有些相同,都響應垃圾回收,然而回收的時間點,卻有些區別,這正是弱引用的特性,在每一次垃圾回收的時候,都會進行弱引用的清除。 最后我們把weakReference進行注釋,讓new PhantomReference<>(new Entry(i, “Phantom”), rq)加入list中,運行程序:

元素:--null0.081: [GC [PSYoungGen: 1800K->488K(3072K)] 1800K->1640K(10240K), 0.0015818 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 元素:--null元素:--null0.083: [GC [PSYoungGen: 2623K->496K(3072K)] 3775K->3760K(10240K), 0.0014629 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 元素:--null對象最后回收前標記:id : 2, type : Phantom對象最后回收前標記:id : 1, type : Phantom元素:--null對象最后回收前標記:id : 0, type : Phantom0.085: [GC [PSYoungGen: 2619K->504K(3072K)] 5883K->5832K(10240K), 0.0017430 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 0.087: [Full GC [PSYoungGen: 504K->0K(3072K)] [ParOldGen: 5328K->5660K(7168K)] 5832K->5660K(10240K) [PSPermGen: 2497K->2496K(21504K)], 0.0114532 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 元素:--null對象進入回收隊列:null元素:--null0.099: [Full GC [PSYoungGen: 2089K->1024K(3072K)] [ParOldGen: 5660K->6683K(7168K)] 7749K->7708K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0082086 secs] [Times: user=0.08 sys=0.02, real=0.01 secs] 對象進入回收隊列:null元素:--null0.108: [Full GC [PSYoungGen: 2076K->2048K(3072K)] [ParOldGen: 6683K->6683K(7168K)] 8760K->8732K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0042951 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 0.112: [Full GC [PSYoungGen: 2048K->2048K(3072K)] [ParOldGen: 6683K->6673K(7168K)] 8732K->8721K(10240K) [PSPermGen: 2496K->2496K(21504K)], 0.0085989 secs] [Times: user=0.09 sys=0.01, real=0.01 secs] 對象進入回收隊列:null對象最后回收前標記:id : 3, type : Phantom對象最后回收前標記:id : 7, type : PhantomException in thread "main" 對象最后回收前標記:id : 6, type : Phantom對象最后回收前標記:id : 5, type : Phantom對象最后回收前標記:id : 4, type : Phantomjava.lang.OutOfMemoryError: Java heap space at com.esy.rice.tool.simple.SimpleJava$Entry.<init>(SimpleJava.java:21) at com.esy.rice.tool.simple.SimpleJava.main(SimpleJava.java:49)

可以看出,PhantomReference進行包裝的對象,不管有沒有gc都不能進行取出,仔細觀察還可以看到,finalize進行打印時,有時候隊列中沒有別回收的對象,這正是PhantomReference的特性,也是唯一的作用,被其引用的對象在遇到垃圾回收時,會進行通知,也就是finalize的調用。


上一篇:文章標題

下一篇:數據結構隊列

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 江都市| 灵寿县| 彩票| 屯门区| 康保县| 罗江县| 保山市| 华蓥市| 出国| 都匀市| 土默特右旗| 柘荣县| 都江堰市| 卢湾区| 明光市| 神农架林区| 阜宁县| 桦甸市| 金寨县| 开鲁县| 临西县| 江川县| 苏尼特左旗| 阿巴嘎旗| 两当县| 万州区| 赤峰市| 抚州市| 富蕴县| 罗山县| 庄浪县| 涞水县| 饶阳县| 焉耆| 门源| 同心县| 兴文县| 桦甸市| 松原市| 林口县| 临湘市|