国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解JAVA 弱引用

詳解JAVA 弱引用

2020-08-18 00:29弗蘭克的貓 Java教程

這篇文章主要介紹了 JAVA 弱引用的相關資料,幫助大家更好的理解和學習java引用對象,感興趣的朋友可以了解下

定義

弱引用是使用WeakReference創(chuàng)建的引用,弱引用也是用來描述非必需對象的,它是比軟引用更弱的引用類型。在發(fā)生GC時,只要發(fā)現(xiàn)弱引用,不管系統(tǒng)堆空間是否足夠,都會將對象進行回收。

說明

弱引用,從名字來看就很弱嘛,這種引用指向的對象,一旦在GC時被掃描到,就逃脫不了被回收的命運。

但是,弱引用指向的對象也并不一定就馬上會被回收,如果弱引用對象較大,直接進到了老年代,那么就可以茍且偷生到Full GC觸發(fā)前,所以弱引用對象也可能存在較長的一段時間。一旦一個弱引用對象被垃圾回收器回收,便會加入到一個引用隊列中(如果有的話)。

弱引用對應的類為WeakReference,舉個栗子:

?
1
2
3
String s = new String("Frank");
WeakReference<String> weakRef = new WeakReference<String>(s);
s = null;

這里我們把s設置為null后,字符串對象便只有弱引用指向它。

弱可達

如果一個對象與GC Roots之間僅存在弱引用,則稱這個對象為弱可達(weakly reachable)對象。

注意

在垃圾回收器回收一個對象前,WeakReference類所提供的get方法會返回其引用對象的強引用,一旦垃圾回收器回收掉該對象之后,get方法將返回null。所以在獲取弱引用對象的代碼中,一定要判斷是否為null,以免出現(xiàn)NullPointerException異常導致應用崩潰。

下面的代碼會讓s再次持有對象的強引用:

?
1
s = weakRef.get();

如果在weakRef包裹的對象被回收前,用強引用關聯(lián)該對象,那這個對象又會變成強可達狀態(tài)。

來看一個簡單的栗子了解一下WeakReference引用的對象是何時被回收的:

?
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class WeakReferenceTest {
 private static final List<Object> TEST_DATA = new LinkedList<>();
 private static final ReferenceQueue<TestClass> QUEUE = new ReferenceQueue<>();
 
 public static void main(String[] args) {
  TestClass obj = new TestClass("Test");
  WeakReference<TestClass> weakRef = new WeakReference<>(obj, QUEUE);
  //可以重新獲得OOMClass對象,并用一個強引用指向它
  //oomObj = weakRef.get();
 
  // 該線程不斷讀取這個弱引用,并不斷往列表里插入數(shù)據(jù),以促使系統(tǒng)早點進行GC
  new Thread(() -> {
   while (true) {
    TEST_DATA.add(new byte[1024 * 100]);
    try {
     Thread.sleep(1000);
    } catch (InterruptedException e) {
     e.printStackTrace();
     Thread.currentThread().interrupt();
    }
    System.out.println(weakRef.get());
   }
  }).start();
 
  // 這個線程不斷讀取引用隊列,當弱引用指向的對象唄回收時,該引用就會被加入到引用隊列中
  new Thread(() -> {
   while (true) {
    Reference<? extends TestClass> poll = QUEUE.poll();
    if (poll != null) {
     System.out.println("--- 弱引用對象被jvm回收了 ---- " + poll);
     System.out.println("--- 回收對象 ---- " + poll.get());
    }
   }
  }).start();
 
  //將強引用指向空指針 那么此時只有一個弱引用指向TestClass對象
  obj = null;
 
  try {
   Thread.currentThread().join();
  } catch (InterruptedException e) {
   e.printStackTrace();
   System.exit(1);
  }
 }
 
 static class TestClass {
  private String name;
 
  public TestClass(String name) {
   this.name = name;
  }
 
  @Override
  public String toString() {
   return "TestClass - " + name;
  }
 }
}

設置一下虛擬機參數(shù):

-verbose:gc -Xms4m -Xmx4m -Xmn2m

運行結果如下:

[GC (Allocation Failure) 1017K->464K(3584K), 0.0014345 secs]
[GC (Allocation Failure) 1483K->536K(3584K), 0.0017221 secs]
[GC (Allocation Failure) 1560K->648K(3584K), 0.0036572 secs]
TestClass - Test
TestClass - Test
TestClass - Test
[GC (Allocation Failure) 1621K->984K(3584K), 0.0011455 secs]
--- 弱引用對象被jvm回收了 ---- java.lang.ref.WeakReference@51a947fe
--- 回收對象 ---- null
null
...省略n個null和幾次GC信息
[Full GC (Ergonomics) 2964K->2964K(3584K), 0.0025450 secs]
[Full GC (Allocation Failure) 2964K->2964K(3584K), 0.0021907 secs]
java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid6860.hprof ...
Heap dump file created [3912229 bytes in 0.011 secs]
Exception in thread "Thread-0" java.lang.OutOfMemoryError: Java heap space
at weakhashmap.WeakReferenceTest.lambda$main$0(WeakReferenceTest.java:22)
at weakhashmap.WeakReferenceTest$$Lambda$1/764977973.run(Unknown Source)
at java.lang.Thread.run(Thread.java:748)

可以看到,其實弱引用也并不是一發(fā)生GC就被回收掉了。

應用場景

如果一個對象僅僅是偶爾使用,并且希望在使用時隨時就能獲取到,但又不想影響此對象的垃圾收集,那么你應該用 WeakReference 來引用該對象。

弱引用可以和一個引用隊列(ReferenceQueue)聯(lián)合使用,如果弱引用所引用的對象被垃圾回收,Java虛擬機就會把這個弱引用加入到與之關聯(lián)的引用隊列中。

一般來說,很少直接使用WeakReference,而是使用WeakHashMap。在WeakHashMap中,內(nèi)部有一個引用隊列,插入的元素會被包裹成WeakReference,并加入隊列中,用來做緩存再合適不過。

在Tomcat的緩存中,其實就用到了WeakHashMap:

?
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
30
31
32
33
34
35
36
37
38
public final class ConcurrentCache<K,V> {
 private final int size;
 private final Map<K,V> eden;
 private final Map<K,V> longterm;
 
 public ConcurrentCache(int size) {
  this.size = size;
  this.eden = new ConcurrentHashMap<>(size);
  this.longterm = new WeakHashMap<>(size);
 }
 
 public V get(K k) {
  // 先從eden中取
  V v = this.eden.get(k);
  if (v == null) {
   // 如果取不到再從longterm中取
   synchronized (longterm) {
    v = this.longterm.get(k);
   }
   // 如果取到則重新放到eden中
   if (v != null) {
    this.eden.put(k, v);
   }
  }
  return v;
 }
 
 public void put(K k, V v) {
  if (this.eden.size() >= size) {
   // 如果eden中的元素數(shù)量大于指定容量,將所有元素放到longterm中
   synchronized (longterm) {
    this.longterm.putAll(this.eden);
   }
   this.eden.clear();
  }
  this.eden.put(k, v);
 }
}

這里有eden和longterm的兩個map,如果對jvm堆了解的話,可以看出tomcat在這里是使用ConcurrentHashMap和WeakHashMap做了類似分代緩存的操作。

在put方法里,在插入鍵值對時,先檢查eden緩存的容量是否超出設定的大小。如果沒有則直接放入eden緩存,如果超了則鎖定longterm將eden中所有的鍵值對都放入longterm。再將eden清空并插入該鍵值對。

在get方法中,也是優(yōu)先從eden中找對應的key,如果沒有則進入longterm緩存中查找,找到后就加入eden緩存并返回。

經(jīng)過這樣的設計,相對常用的對象都能在eden緩存中找到,不常用(有可能被銷毀的對象)的則進入longterm緩存。而longterm的key的實際對象沒有其他引用指向它時,gc就會自動回收heap中該弱引用指向的實際對象,并將弱引用放入其引用隊列中。

弱引用與軟引用對比

弱引用與軟引用的區(qū)別在于:

  1. 只具有弱引用的對象擁有更短暫的生命周期。
  2. 被垃圾回收器回收的時機不一樣,在垃圾回收器線程掃描它所管轄的內(nèi)存區(qū)域的過程中,一旦發(fā)現(xiàn)了只具有弱引用的對象,不管當前內(nèi)存空間足夠與否,都會回收它的內(nèi)存。而被軟引用關聯(lián)的對象只有在內(nèi)存不足時才會被回收。
  3. 弱引用不會影響GC,而軟引用會一定程度上對GC造成影響。

相似之處:都是用來描述非必需對象的。

那么什么時候用SoftReference,什么時候用WeakReference呢?

如果緩存的對象是比較大的對象,使用頻率相對較高的對象,那么使用SoftReference會更好,因為這樣能讓緩存對象有更長的生命周期。

如果緩存對象都是比較小的對象,使用頻率一般或者相對較低,那么使用WeakReference會更合適。

當然,如果實在不知道選哪個,一般而言,用作緩存時使用WeakHashMap都不會有太大問題。

小結

  • 弱引用是比軟引用更弱的引用類型
  • 弱引用不能延長對象的生命周期,一旦對象只剩下弱引用,它就隨時可能會被回收
  • 可以通過弱引用獲取對象的強引用
  • 弱引用適合用作緩存

以上就是詳解 JAVA 弱引用的詳細內(nèi)容,更多關于java 弱引用的資料請關注服務器之家其它相關文章!

原文鏈接:https://cloud.tencent.com/developer/article/1365719

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 色婷婷av一区二区三区大白胸 | 亚洲午夜一区 | 操操网站 | 成人中文字幕在线观看 | 午夜成人在线视频 | 国产福利91精品一区二区三区 | 北条麻妃在线一区二区三区 | 依人在线 | 久久久区| 在线视频91 | 成人av片在线观看 | 国产999精品久久久久 | 亚洲国产精品福利 | 成人亚洲精品777777大片 | 综合久久亚洲 | 国产欧美日韩一区 | 青青草视频在线免费观看 | 日韩精品 | 欧美一级黄色片 | 日本成片视频 | www,四虎 | 日韩成人精品在线 | 成人精品三级av在线看 | 欧美激情专区 | 激情综合久久 | 久久毛片 | 免费成人高清在线视频 | 国产亚洲精品一区二区 | 动漫卡通精品一区二区三区介绍 | 看片久久| 久久专区 | 国产精品毛片一区二区三区 | 欧美精品成人 | 免费看国产片在线观看 | 四虎影院最新地址 | 一级黄色毛片免费观看 | 亚洲人免费视频 | 亚洲视频在线观看免费 | 中文字幕一区二区三区四区 | 在线欧美日韩 | 中文字幕亚洲欧美日韩在线不卡 |