成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

別再找了,一文徹底解析Java 中的弱引用

開發 后端
本文會通過對弱引用的定義講起,然后通過案例的使用一步一步的深入源碼進行分析其原理,從而讓讀者深刻的理解什么是弱引用,如何使用弱引用,什么場景下會使用弱引用,弱引用可以解決什么樣的問題,以及它的源碼實現是怎樣的,其中會涉及的內存溢出,垃圾回收原理

概覽

本文會通過對弱引用的定義講起,然后通過案例的使用一步一步的深入源碼進行分析其原理,從而讓讀者深刻的理解什么是弱引用,如何使用弱引用,什么場景下會使用弱引用,弱引用可以解決什么樣的問題,以及它的源碼實現是怎樣的,其中會涉及的內存溢出,垃圾回收原理

作用:

jdk 官網解釋:

  • 弱引用主要應用在不阻止它的key或者value 被回收的mapping。直接貼英文吧,翻譯水平有限(weak references are for implementing canonicalizing mappings that do not prevent their keys (or values) from being reclaimed)

個人理解:

  • 弱引用的出現就是為了垃圾回收服務的。它引用一個對象,但是并不阻止該對象被回收。如果使用一個強引用的話,只要該引用存在,那么被引用的對象是不能被回收的。弱引用則沒有這個問題。在垃圾回收器運行的時候,如果一個對象的所有引用都是弱引用的話,該對象會被回收

案例深度解析

理想的情況下,我們希望當我們不再使用一個對象的時候,能夠在gc 發生的時候就把它回收掉。但是有些時候,由于我們的粗忽,在壞的情況下會導致內存溢出。這種案例尤其發生在一個生命使用周期很長的map 存放了很多實際使用生命周期短的對象。請看下面這個例子

別再找了,一文徹底解析Java 中的弱引用

別再找了,一文徹底解析Java 中的弱引用

運行后輸出結果:

  1. gc 發生前:1 
  2. 開始通知GC 
  3. gc 發生后:1 

從輸出的結果可以看到,即使我們通過把key和value 設置為null 來告訴jvm,我們不再使用這個對象了,map 里面對象依然沒有被GC 回收,因為key和value 被一個強引用map 指向,根據可達性判斷,垃圾回收器是不能回收掉key和value 這個對象的。map 被定義為statis 的靜態變量,是一個使用生命周期很長的對象。在strongTest()方法中存在了一個key和value 的局部變量,它隨著方法的執行完,這個變量的生命使用周期就結束了,但是粗糙的程序員忘記remove 了,這個時候垃圾回收器是不能回收它的。如果這種生命周期相對短的對象很多,最終就有可能消耗掉JVM中全部的內存。

但是這里我有一個好奇,假如這里的key和value 指向的對象在執行完strongTest()方法 以后用不著了,但是我可能又不是很好的判斷去主動調用remove 來移除它。想要垃圾回收器自己判斷回收掉可不可以呢?答案其實是可以的,這個時候就是弱引用上場了,請看下面程序

別再找了,一文徹底解析Java 中的弱引用

別再找了,一文徹底解析Java 中的弱引用

運行上面代碼輸出結果

  1. gc 發生前:1 
  2. 開始通知GC 
  3. gc 發生后:0 

從輸出結果0,我們可以判斷已經成功被垃圾回收了。what?整個過程我們只是把HashMap 換成了WeakHashMap,并且key 由String 換成了WeakReference。其實就是由于字符串只有弱引用指向,所以可以被垃圾回收掉。是不是很簡單,如果到這里你就停止研究弱引用了,那就太暴殄天物了

WeakHashMap 深度解析

上面的程序片段中,其實只有key 設置了為弱引用new WeakReference<>(key),那正常也就只有這個key 對應的內存被回收而已,由于沒有調用remove ,里面的value 和entry 也是不會回收掉的,那為什么最后輸出的size 是0 呢? 很好的問題,我們深入去看WeakHashMap 的源碼,我們發現了一個神奇的方法expungeStaleEntries()。在看源碼之前先解析下引用隊列的概念: 在弱引用被回收的時候會把該對象放到引用隊列中,也就意味著從引用隊列中獲取的對象都是被回收的對象,先解釋到這里,足以滿足我們下面的源碼分析了,接下來會做詳細的解析

別再找了,一文徹底解析Java 中的弱引用

別再找了,一文徹底解析Java 中的弱引用

從上面的代碼片段,大概的意思就是從引用隊列里面取出被回收的對象,然后和WeakHashMap 中的對象查找,找到之后就把對應的value 也設置為null,并且把對應的entry 設置為null,來告訴GC 去回收它。從源碼可以看到expungeStaleEntries() 這個方法在執行WeakHashMap中的任何方法的時候都會被調用到的

別再找了,一文徹底解析Java 中的弱引用

到這里也就完全明白為什么value 不設置為弱引用和沒有顯性的調用remove 方法也可以回收掉了

引用隊列

從上面的的源碼中,我們大概知道了引用隊列的使用,那為什么要使用引用隊列呢?假如沒有引用隊列,上面的例子我們就需要遍歷全部的元素一個一個的去找,如果數量少那還好,如果數量多的時候,肯定就會出現一些性能問題。有了引用隊列那就輕松可以解決上面的問題了。從WeakReference 源碼中我們可以看到有兩個構造函數,第二個是需要傳入引用隊列的

別再找了,一文徹底解析Java 中的弱引用

引用隊列hello word

別再找了,一文徹底解析Java 中的弱引用

使用中需要注意的細節: 由于弱引用的對象在GC 發生的時候都可能會被回收掉,所以在使用之前我們都需要判斷下是否為null 來避免空指針異常

別再找了,一文徹底解析Java 中的弱引用

總結

  1. 弱引用的出現是為了垃圾回收的
  2. 一個對象只有弱引用指向它的時候,它是可以被回收的
  3. 弱引用是在GC 發生的時候就進行回收,不管當時內存是否充足
  4. 如果你在創建弱引用指定一個引用隊列的話,弱引用對象被回收的時候,會把該對象放入引用隊列中
  5. 為了安全使用,每次都要判斷下是否為空來判斷該對象是否已經被回收,來避免空指針異常

 

責任編輯:未麗燕 來源: 安卓巴士
相關推薦

2024-11-14 07:20:00

2024-01-10 08:36:10

延時關閉訂單

2021-06-30 08:45:02

內存管理面試

2020-03-18 14:00:47

MySQL分區數據庫

2022-06-07 10:13:22

前端沙箱對象

2023-10-27 08:15:45

2020-12-07 06:19:50

監控前端用戶

2021-07-08 10:08:03

DvaJS前端Dva

2023-05-29 08:45:45

Java注解數據形式

2024-07-18 08:00:00

2020-06-03 08:19:00

Kubernetes

2019-08-27 14:46:59

ElasticSearES數據庫

2021-08-31 07:02:20

Diff算法DOM

2024-05-13 10:45:25

中介模式面向對象數量

2019-11-06 17:30:57

cookiesessionWeb

2024-05-10 08:43:04

外觀模式接口系統

2023-12-15 09:45:21

阻塞接口

2023-12-12 07:31:51

Executors工具開發者

2024-05-09 09:09:19

組合模式對象

2015-11-02 17:20:00

Java弱引用
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 老外几下就让我高潮了 | 日韩中文一区二区三区 | 粉嫩一区二区三区性色av | 精品久久国产 | 国产精品1区2区3区 男女啪啪高潮无遮挡免费动态 | 中文字幕一区二区三区在线观看 | 国产精品久久久久久一区二区三区 | 欧美日韩国产精品一区二区 | 午夜激情影院 | 在线电影日韩 | 日韩电影免费在线观看中文字幕 | 黄色大全免费看 | 免费视频一区二区三区在线观看 | 91精品一区二区三区久久久久 | 亚洲精品日韩视频 | 国产精品久久久久久二区 | 久久激情视频 | 精品欧美久久 | 在线国产99| xx视频在线观看 | 久久久久国色av免费观看性色 | 亚洲精品乱码久久久久久蜜桃91 | 久草精品视频 | 免费色网址 | 欧美激情99 | 久草在线| 99九九视频 | 欧美一级网站 | 成人精品高清 | 91精品国产色综合久久不卡98 | 狠狠色综合欧美激情 | 欧美三区在线观看 | 欧美在线a | 日韩在线观看一区 | 久久夜视频 | 精品一区二区三区四区在线 | 日韩在线播放中文字幕 | 日韩在线观看 | 成人h电影在线观看 | 久久久精品国产 | 亚洲国产一区二区三区在线观看 |