电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

java中的Reference類型用法說明

瀏覽:75日期:2022-08-23 17:17:24

本文簡要總結(jié)java中的Reference類型。

最近在研讀jdk并發(fā)框架,其中AQS是重點,由于我打破砂鍋問到底的輕微強迫癥,google了AQS作者Doug Lea的論文原文[The java.util.concurrent Synchronizer Framework],有興趣的同學(xué)可以自行下載。其中談到設(shè)計同步框架的核心是選擇一個嚴格意義上的FIFO隊列,作為阻塞線程隊列并對其進行維護。

對此主要由兩種選擇,一個是MCS鎖,另一個時CLH鎖。因為CLH鎖比MCS對取消和超時的處理更方便,所以AQS就選擇將CLH鎖作為基礎(chǔ)對其進行改進。于是我又打算先弄懂什么是CLH鎖,在網(wǎng)上搜索了一圈之后找到很多人對CLH鎖進行了java實現(xiàn),實現(xiàn)中用到了ThreadLocal類型,于是我發(fā)現(xiàn)我好像對ThreadLocal也不太熟,于是去看openjdk的源碼,又發(fā)現(xiàn)ThreadLocal的內(nèi)部類ThreadLocalMap中的Entry是繼承自WeakReference,好了,既然這幾個我好像都沒弄得很明白過,所以我決定先了解一下Reference。

在我們平時開發(fā)過程中很少會遇到需要與各種不同類型的reference打交道的時候,所以很多時候我們在自己寫的代碼中很少會碰到需要使用不同的reference類型,可能很多人也會向我這樣,想要深入學(xué)習(xí)一下jdk源碼或者其他某些框架的源碼的時候才會看到諸如WeakReference這樣的類型。

問題

假設(shè)在一個應(yīng)用中,需要從一個名為test的數(shù)據(jù)庫表中獲取數(shù)據(jù)。但凡有點經(jīng)驗的開發(fā)人員都會避免應(yīng)用獲取相同的數(shù)據(jù)每次都去查詢數(shù)據(jù)庫,因為I/O操作過去頻繁勢必會降低應(yīng)用性能。

顯然,我們首先想到的就是使用緩存。應(yīng)用首先查詢緩存,如果需要的數(shù)據(jù)存在直接拿來用就好;如果緩存未命中,才去數(shù)據(jù)庫查詢,并且把查詢到的數(shù)據(jù)放入緩存,以便下次應(yīng)用發(fā)起相同請求時可以直接從緩存獲取數(shù)據(jù)而不用再次去數(shù)據(jù)庫查詢。

使用緩存會提高性能嗎?

答案是這需要根據(jù)具體情況分析,如果從test獲取需要緩存的數(shù)據(jù)量較少,使用緩存會非常合適且一定會提升性能。但假若需要從test表查詢放到緩存里的數(shù)據(jù)量非常大,那就會出現(xiàn)一個問題:由于數(shù)據(jù)量過大可能會導(dǎo)致內(nèi)存不足,而不單單是提升性能了。假如說把表中所有數(shù)據(jù)都放入緩存,那么緩存的可能會占據(jù)大部分jvm的內(nèi)存或者索性直接產(chǎn)生一個OOM錯誤。

解決方案

最佳的方案是如果我們可以創(chuàng)造一種可以按需擴展和收縮的動態(tài)緩存,當我們的數(shù)據(jù)量需要而內(nèi)存充裕的時候可以適當增加,但內(nèi)存不足是可以按不同方案對其進行回收。

目的

這里引出的一個問題,就是為什么要在Java中使用不同類型的reference?我們的應(yīng)用在運行過程中會產(chǎn)生很多對象,這些對象駐留在內(nèi)存中,它們大小不同,重要性不同,使用頻率不同,生命周期不同,比如有些對象只要應(yīng)用啟動就一直存活直到應(yīng)用停止,而有些對象生命周期與創(chuàng)建它的線程相同,還有些對象只作臨時變量短時間就消亡,再比如某些緩存數(shù)據(jù),內(nèi)存充裕的時候可以存活,內(nèi)存不足的時候可能需要被首先犧牲被回收,所以很容易想象對于不同的對象,我們希望對他們的創(chuàng)建銷毀采取不同的策略,可是不幸的是java不像C一樣可以由開發(fā)者決定對象的析構(gòu)銷毀,而是將管理內(nèi)存的活統(tǒng)一交給了jvm進行g(shù)c,但jvm顯然不知道這些對象的區(qū)別。

于是設(shè)計者們在java 1.2加入了reference,使jvm可以對不同的reference對象采取不同的回收策略以達到提高應(yīng)用性能的目的。

java.lang.ref 包

實際上java.lang.ref包中就有以下幾種不同的reference類型,分別是:

StrongReference

SoftReference

WeakReference

PhantomReference

FinalReference

java中的Reference類型用法說明

StrongReference

我們發(fā)現(xiàn)在類圖中我們并沒有發(fā)現(xiàn) StrongReference 類型,原因是我們平時寫的代碼基本上都是 StrongReference 。我們最常的創(chuàng)建對象方式就是 new 一個對象,然后將其賦值給一個聲明為這個對象的類型及其父類的引用。如果對象有一個 StrongReference ,那么這個對象將不會被gc回收。

舉例

HelloWorld hello = new HelloWorld();

這里 hello 就是一個 HelloWorld 對象的 StrongReference。

SoftReference

如果一個對象沒有 StrongReference 但存在一個 SoftReference ,那么 gc 將會在虛擬機需要釋放一些內(nèi)存的時候回收這個對象。可以通過對對象的 SoftReference 調(diào)用 get() 方法獲取該對象。如果這個對象沒有被 gc 回收,則返回此對象,否則返回 null 。

WeakReference

如果一個對象沒有 StrongReference 但有存在一個 WeakReference ,那么 gc 將會在下一次運行時對其進行回收,哪怕虛擬機的內(nèi)存還足夠多。

PhantomReference 與 FinalReference

如果某個對象沒有以上這些類型的引用,那么它可能有一個 PhantomReference 。PhantomReference 不能用于直接訪問對象。調(diào)用 get() 方法都會返回 null 。

FinalReference 與虛擬機密切相關(guān),這里先挖個坑,下次再具體解析。

對象可達性判斷

當前主流java虛擬機都是采用 GC Roots Tracing 算法,比如 Sun 的 Hotspot 虛擬機便是采用該算法。java虛擬機進行g(shù)c時,判斷一個對象的被引用情況決定是否回收,都是從根節(jié)點引用(Root set of Reference)開始標識可達路徑的。對于某個對象可能會存在其多個引用,且這多個引用的類型不同。

如下圖所示:

java中的Reference類型用法說明

Root Tracing 算法根據(jù)以下兩個原則標記對象的可達性:

單一路徑中,以最弱的引用為準

多路徑中,以最強的引用為準

如上圖所示,對對象4存在3條引用路徑:(1)(4),(2)(5),(3)(6)。那么從根對象到對象4的最強引用時(2)(5),因為(2)和(5)都是強引用。如果對象4僅存在一條(1)(4)引用,那么對它的引用就是最弱的引用為準,也就是 SoftReference ,對象4就是 softly-reachable 對象。

不同類型 reference java 代碼舉例

package com.example.reference;import java.lang.ref.PhantomReference;import java.lang.ref.ReferenceQueue;import java.lang.ref.SoftReference;import java.lang.ref.WeakReference;public class ReferenceExample { private String status ='Hi I am active'; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } @Override public String toString() { return 'ReferenceExample [status=' + status + ']'; } public void strongReference() { ReferenceExample ex = new ReferenceExample(); System.out.println(ex); } public void softReference() { SoftReference<ReferenceExample> ex = new SoftReference<ReferenceExample>(getRefrence()); System.out.println('Soft refrence :: ' + ex.get()); } public void weakReference() { int counter=0; WeakReference<ReferenceExample> ex = new WeakReference<ReferenceExample>(getRefrence()); while(ex.get()!=null) { counter++; System.gc(); System.out.println('Weak reference deleted after:: ' + counter + ex.get()); } } public void phantomReference() throws InterruptedException { final ReferenceQueue queue = new ReferenceQueue(); PhantomReference<ReferenceExample> ex = new PhantomReference<ReferenceExample>(getRefrence(),queue); System.gc(); queue.remove(); System.out.println('Phantom reference deleted after'); } private ReferenceExample getRefrence() { return new ReferenceExample(); } public static void main(String[] args) { ReferenceExample ex = new ReferenceExample(); ex.strongReference(); ex.softReference(); ex.weakReference(); try { ex.phantomReference(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } }}Output :ReferenceExample [status=Hi I am active]Soft refrence :: ReferenceExample [status=Hi I am active]Weak reference deleted after:: 1nullPhantom reference deleted after

總結(jié)

通過對以上各類型的 reference 介紹可以發(fā)現(xiàn)其實 reference 主要是用來與虛擬機 gc 進行交互,使得虛擬機根據(jù)對象的不同引用類型,對其采用不同的內(nèi)存回收策略。

strong 引用的對象正常情況下不會被回收,soft 引用的對象會在出現(xiàn) OOM 錯誤之前被回收,而 weak 引用的對象在下一次 gc 的時候就會被回收,對 reference 的基本理解就差不多了。

至于 PhantomReference 與 FinalReference 下次再講。

以上這篇java中的Reference類型用法說明就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: RTO换向阀_VOC高温阀门_加热炉切断阀_双偏心软密封蝶阀_煤气蝶阀_提升阀-湖北霍科德阀门有限公司 | Safety light curtain|Belt Sway Switches|Pull Rope Switch|ultrasonic flaw detector-Shandong Zhuoxin Machinery Co., Ltd | 注塑_注塑加工_注塑模具_塑胶模具_注塑加工厂家_深圳环科 | 通信天线厂家_室分八木天线_对数周期天线_天线加工厂_林创天线源头厂家 | 高压包-点火器-高压发生器-点火变压器-江苏天网 | 鑫铭东办公家具一站式定制采购-深圳办公家具厂家直销 | 大功率金属激光焊接机价格_不锈钢汽车配件|光纤自动激光焊接机设备-东莞市正信激光科技有限公司 定制奶茶纸杯_定制豆浆杯_广东纸杯厂_[绿保佳]一家专业生产纸杯碗的厂家 | 全温度恒温培养摇床-大容量-立式-远红外二氧化碳培养箱|南荣百科 | 南京办公用品网-办公文具用品批发-打印机耗材采购 | 杭州翻译公司_驾照翻译_专业人工翻译-杭州以琳翻译有限公司官网 组织研磨机-高通量组织研磨仪-实验室多样品组织研磨机-东方天净 | 佛山商标注册_商标注册代理|专利注册申请_商标注册公司_鸿邦知识产权 | 钢格板|镀锌钢格板|热镀锌钢格板|格栅板|钢格板|钢格栅板|热浸锌钢格板|平台钢格板|镀锌钢格栅板|热镀锌钢格栅板|平台钢格栅板|不锈钢钢格栅板 - 专业钢格板厂家 | 洛阳防爆合格证办理-洛阳防爆认证机构-洛阳申请国家防爆合格证-洛阳本安防爆认证代办-洛阳沪南抚防爆电气技术服务有限公司 | 机床导轨_导轨板_滚轮导轨-上海旻佑精密机械有限公司 | 玻璃钢型材-玻璃钢风管-玻璃钢管道,生产厂家-[江苏欧升玻璃钢制造有限公司] | 德国UST优斯特氢气检漏仪-德国舒赐乙烷检测仪-北京泽钏 | 沥青灌缝机_路面灌缝机_道路灌缝机_沥青灌缝机厂家_济宁萨奥机械有限公司 | 渣油泵,KCB齿轮泵,不锈钢齿轮泵,重油泵,煤焦油泵,泊头市泰邦泵阀制造有限公司 | 岩棉板|岩棉复合板|聚氨酯夹芯板|岩棉夹芯板|彩钢夹芯板-江苏恒海钢结构 | 二手电脑回收_二手打印机回收_二手复印机回_硒鼓墨盒回收-广州益美二手电脑回收公司 | 常州企业采购平台_常州MRO采购公司_常州米孚机电设备有限公司 | 有机废气处理-rto焚烧炉-催化燃烧设备-VOC冷凝回收装置-三梯环境 | 聚合氯化铝厂家-聚合氯化铝铁价格-河南洁康环保科技 | 熔体泵_熔体出料泵_高温熔体泵-郑州海科熔体泵有限公司 | 手术室净化厂家-成都做医院净化工程的公司-四川华锐-15年特殊科室建设经验 | 机房监控|动环监控|动力环境监控系统方案产品定制厂家 - 迈世OMARA | 防水套管厂家-柔性防水套管-不锈钢|刚性防水套管-天翔管道 | 新疆乌鲁木齐网站建设-乌鲁木齐网站制作设计-新疆远璨网络 | 光谱仪_积分球_分布光度计_灯具检测生产厂家_杭州松朗光电【官网】 | 一体化净水器_一体化净水设备_一体化水处理设备-江苏旭浩鑫环保科技有限公司 | 管理会计网-PCMA初级管理会计,中级管理会计考试网站 | 槽钢冲孔机,槽钢三面冲,带钢冲孔机-山东兴田阳光智能装备股份有限公司 | 干粉砂浆设备_干混砂浆生产线_腻子粉加工设备_石膏抹灰砂浆生产成套设备厂家_干粉混合设备_砂子烘干机--郑州铭将机械设备有限公司 | 非小号行情 - 专业的区块链、数字藏品行情APP、金色财经官网 | 亮点云建站-网站建设制作平台 | SOUNDWELL 编码器|电位器|旋转编码器|可调电位器|编码开关厂家-广东升威电子制品有限公司 | 紧急泄压人孔_防爆阻火器_阻火呼吸阀[河北宏泽石化] | 磨煤机配件-高铬辊套-高铬衬板-立磨辊套-盐山县宏润电力设备有限公司 | 钢托盘,铁托盘,钢制托盘,镀锌托盘,饲料托盘,钢托盘制造商-南京飞天金属13260753852 | 四探针电阻率测试仪-振实密度仪-粉末流动性测定仪-宁波瑞柯微智能 | MTK核心板|MTK开发板|MTK模块|4G核心板|4G模块|5G核心板|5G模块|安卓核心板|安卓模块|高通核心板-深圳市新移科技有限公司 |