日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

JVM学习笔记之-垃圾回收相关概念 System.gc()的理解 内存溢出与内存泄漏 STW 垃圾回收的并行与并发 安全点与安全区域 再谈引用:强引用 软引用 弱引用 虚引用 终结器引用

發(fā)布時(shí)間:2024/4/15 编程问答 31 豆豆

System.gc()的理解

在默認(rèn)情況下,通過(guò)System.gc()或者Runtime. getRuntime ( ).gc ()的調(diào)用,會(huì)顯式觸發(fā)Full GC,同時(shí)對(duì)老年代和新生代進(jìn)行回收,嘗試釋放被丟棄對(duì)象占用的內(nèi)存。

然而system.gc()調(diào)用附帶一個(gè)免責(zé)聲明,無(wú)法保證對(duì)垃圾收集器的調(diào)用。

JVM實(shí)現(xiàn)者可以通過(guò)System.gc ()調(diào)用來(lái)決定JVM的GC行為。而一般情況下,垃圾回收應(yīng)該是自動(dòng)進(jìn)行的,無(wú)須手動(dòng)觸發(fā),否則就太過(guò)于麻煩了。在一些特殊情況下,如我們正在編寫一個(gè)性能基準(zhǔn),我們可以在運(yùn)行之間調(diào)用System.gc ()。

代碼解釋上述對(duì) System.gc()的描述

package com.fs.str;public class SystemGCTest {public static void main(String[] args) {new SystemGCTest();System.gc();//提醒jvm的垃圾回收器執(zhí)行g(shù)c,但是不確定是否馬上執(zhí)行g(shù)c// System.gc(); 的底層就是 Runtime.getRuntime().gc();//System.runFinalization(); 此方法就能保證 System.gc();能保證對(duì)垃圾收集器的調(diào)用}@Overrideprotected void finalize() throws Throwable {super.finalize();System.out.println( "systemGCTest重寫了finalize()");//注釋掉System.runFinalization();//運(yùn)行多次發(fā)現(xiàn)有的時(shí)候會(huì)執(zhí)行此方法,有的時(shí)候不執(zhí)行,就說(shuō)明System.gc();方法并不保證對(duì)垃圾收集器的調(diào)用}}

內(nèi)存溢出與內(nèi)存泄漏

內(nèi)存溢出(OOM )

內(nèi)存溢出相對(duì)于內(nèi)存泄漏來(lái)說(shuō),盡管更容易被理解,但是同樣的,內(nèi)存溢出也是引發(fā)程序崩潰的罪魁禍?zhǔn)字弧?/p>

由于cc一直在發(fā)展,所有一般情況下,除非應(yīng)用程序占用的內(nèi)存增長(zhǎng)速度非常快,造成垃圾回收已經(jīng)跟不上內(nèi)存消耗的速度,否則不太容易出現(xiàn)OOM的情況。

大多數(shù)情況下,GC會(huì)進(jìn)行各種年齡段的垃圾回收,實(shí)在不行了就放大招,來(lái)一次獨(dú)占式的Full Gc操作,這時(shí)候會(huì)回收大量的內(nèi)存,供應(yīng)用程序繼續(xù)使用。

javadoc中對(duì)OutOfMemoryError的解釋是,沒(méi)有空閑內(nèi)存,并且垃圾收集器也無(wú)法提供更多內(nèi)存。

首先說(shuō)沒(méi)有空閑內(nèi)存的情況:說(shuō)明Java虛擬機(jī)的堆內(nèi)存不夠。原因有二:

(1) Java虛擬機(jī)的堆內(nèi)存設(shè)置不夠。

比如:可能存在內(nèi)存泄漏問(wèn)題;也很有可能就是堆的大小不合理,比如我們要處理比較可觀的數(shù)據(jù)量,但是沒(méi)有顯式指定JVM堆大小或者指定數(shù)值偏小。我們可以通過(guò)參數(shù)-Xms.-Xmx來(lái)調(diào)整。

(2)代碼中創(chuàng)建了大量大對(duì)象,并且長(zhǎng)時(shí)間不能被垃圾收集器收集(存在被引用)

對(duì)于老版本的oracle JDK,因?yàn)橛谰么拇笮∈怯邢薜?#xff0c;并且JVM對(duì)永久代垃圾回收(如,常量池回收、卸載不再需要的類型)非常不積極,所以當(dāng)我們不斷添加新類型的時(shí)候,永久代出現(xiàn)outOfMemoryError也非常多見,尤其是在運(yùn)行時(shí)存在大量動(dòng)態(tài)類型生成的場(chǎng)合;類似intern字符串緩存占用太多空間,也會(huì)導(dǎo)致ooM問(wèn)題。對(duì)應(yīng)的異常信息,會(huì)標(biāo)記出來(lái)和永久代相關(guān):“java.lang.OutOfMemoryError: PermGen space"

隨著元數(shù)據(jù)區(qū)的引入,方法區(qū)內(nèi)存已經(jīng)不再那么窘迫,所以相應(yīng)的oOM有所改觀,出現(xiàn)00M,異常信息則變成了:“java.lang.OutOfMemoryError: Metaspace"。直接內(nèi)存不足,也會(huì)導(dǎo)致OOM。

這里面隱含著一層意思是,在拋出outOfMemoryError之前,通常垃圾收集器會(huì)被觸發(fā),盡其所能去清理出空間。

例如:在引用機(jī)制分析中,涉及到JVM會(huì)去嘗試回收軟引用指向的對(duì)象等。

在java.nio.BIts.reserveMemory()方法中,我們能清楚的看到,System…gc()會(huì)被調(diào)用,以清理空間。

當(dāng)然,也不是在任何情況下垃圾收集器都會(huì)被觸發(fā)的

比如,我們?nèi)シ峙湟粋€(gè)超大對(duì)象,類似一個(gè)超大數(shù)組超過(guò)堆的最大值,JVM可判斷出垃圾收集并不能解決這個(gè)問(wèn)題,所以直接拋出OutOfMemoryError。

內(nèi)存泄漏(Memory Leak)

也稱作“存儲(chǔ)滲漏”。嚴(yán)格來(lái)說(shuō)只有對(duì)象不會(huì)再被程序用到了,但是GC又不能回收他們的情況,才叫內(nèi)存泄漏。

但實(shí)際情況很多時(shí)候一些不太好的實(shí)踐(或疏忽)會(huì)導(dǎo)致對(duì)象的生命周期變得很長(zhǎng)甚至導(dǎo)致OOM,也可以叫做寬泛意義上的“內(nèi)存泄漏”。

盡管內(nèi)存泄漏并不會(huì)立刻引起程序崩潰,但是一旦發(fā)生內(nèi)存泄漏,程序中的可用內(nèi)存就會(huì)被逐步蠶食,直至耗盡所有內(nèi)存,最終出現(xiàn)OutOfMemory異常導(dǎo)致程序崩潰。

注意,這里的存儲(chǔ)空間并不是指物理內(nèi)存,而是指虛擬內(nèi)存大小,這個(gè)虛擬內(nèi)存大小取決于磁盤交換區(qū)設(shè)定的大小。

內(nèi)存泄漏(Memory Leak)舉例:

1、單例模式

單例的生命周期和應(yīng)用程序是一樣長(zhǎng)的,所以單例程序中,如果持有對(duì)外部對(duì)象的引用的話,那么這個(gè)外部對(duì)象是不能被回收的,則會(huì)導(dǎo)致內(nèi)存泄漏的產(chǎn)生。

2、一些提供close的資源未關(guān)閉導(dǎo)致內(nèi)存泄漏

數(shù)據(jù)庫(kù)連接(dataSourse.getConnection()),網(wǎng)絡(luò)連接(socket)和io連接必須手動(dòng)close,否則是不能被回收的。

Stop The World

stop-the-world ,簡(jiǎn)稱STW,指的是GC事件發(fā)生過(guò)程中,會(huì)產(chǎn)生應(yīng)用程序的停頓。停頓產(chǎn)生時(shí)整個(gè)應(yīng)用程序線程都會(huì)被暫停,沒(méi)有任何響應(yīng),有點(diǎn)像卡死的感覺(jué),這個(gè)停頓稱為STW。

可達(dá)性分析算法中枚舉根節(jié)點(diǎn)(GC Roots)會(huì)導(dǎo)致所有Java執(zhí)行線程停頓。
√分析工作必須在一個(gè)能確保一致性的快照中進(jìn)行
√一致性指整個(gè)分析期間整個(gè)執(zhí)行系統(tǒng)看起來(lái)像被凍結(jié)在某個(gè)時(shí)間點(diǎn)上
如果出現(xiàn)分析過(guò)程中對(duì)象引用關(guān)系還在不斷變化,則分析結(jié)果的準(zhǔn)確性無(wú)法保證

被STW中斷的應(yīng)用程序線程會(huì)在完成GC之后恢復(fù),頻繁中斷會(huì)讓用戶感覺(jué)像是網(wǎng)速不快造成電影卡帶一樣,所以我們需要減少STW的發(fā)生。

STW事件和采用哪款GC無(wú)關(guān),所有的GC都有這個(gè)事件。

哪怕是G1也不能完全避免stop-the-world 情況發(fā)生,只能說(shuō)垃圾回收器越來(lái)越優(yōu)秀,回收效率越來(lái)越高,盡可能地縮短了暫停時(shí)間。

STW是JVM在后臺(tái)自動(dòng)發(fā)起和自動(dòng)完成的。在用戶不可見的情況下,把用戶正常的工作線程全部停掉。

開發(fā)中不要用system.gc ();會(huì)導(dǎo)致stop-the-world的發(fā)生。

垃圾回收的并行與并發(fā)

并發(fā)(Concurrent)

在操作系統(tǒng)中,是指一個(gè)時(shí)間段中有幾個(gè)程序都處于已啟動(dòng)運(yùn)行到運(yùn)行完畢之間,且這幾個(gè)程序都是在同一個(gè)處理器上運(yùn)行。

并發(fā)不是真正意義上的“同時(shí)進(jìn)行”,只是CPU把一個(gè)時(shí)間段劃分成幾個(gè)時(shí)間片段(時(shí)間區(qū)間),然后在這幾個(gè)時(shí)間區(qū)間之間來(lái)回切換,由于CPU處理的速度非常快,只要時(shí)間間隔處理得當(dāng),即可讓用戶感覺(jué)是多個(gè)應(yīng)用程序同時(shí)在進(jìn)行。

并行(Parallel)?

當(dāng)系統(tǒng)有一個(gè)以上CPU時(shí),當(dāng)一個(gè)CPU執(zhí)行一個(gè)進(jìn)程時(shí),另一個(gè)CPU可以執(zhí)行另一個(gè)進(jìn)程,兩個(gè)進(jìn)程互不搶占CPU資源,可以同時(shí)進(jìn)行,我們稱之為并行(Parallel)。

其實(shí)決定并行的因素不是CPU的數(shù)量,而是cPU的核心數(shù)量,比如一個(gè)cPU多個(gè)核也可以并行。

適合科學(xué)計(jì)算,后臺(tái)處理等弱交互場(chǎng)景

并發(fā)vs 并行

二者對(duì)比:

并發(fā),指的是多個(gè)事情,在同一時(shí)間段內(nèi)同時(shí)發(fā)生了。
并行,指的是多個(gè)事情,在同一時(shí)間點(diǎn)上同時(shí)發(fā)生了。

并發(fā)的多個(gè)任務(wù)之間是互相搶占資源的。
并行的多個(gè)任務(wù)之間是不互相搶占資源的。

只有在多CPU或者一個(gè)CPU多核的情況中,才會(huì)發(fā)生并行。
否則,看似同時(shí)發(fā)生的事情,其實(shí)都是并發(fā)執(zhí)行的。

垃圾回收的并發(fā)與并行

并發(fā)和并行,在談?wù)摾占鞯纳舷挛恼Z(yǔ)境中,它們可以解釋如下:

并行(Parallel):指多條垃圾收集線程并行工作,但此時(shí)用戶線程仍處于等待狀態(tài)。

如ParNew、Parallel Scavenge、Parallel old;

串行(serial)

相較于并行的概念,單線程執(zhí)行。

如果內(nèi)存不夠,則程序暫停,啟動(dòng)TVM垃圾回收器進(jìn)行垃圾回收。回收完,再啟動(dòng)程序的線程。

并發(fā)(Concurrent):指用戶線程與垃圾收集線程同時(shí)執(zhí)行(但不一定是并行的,可能會(huì)交替執(zhí)行),垃圾回收線程在執(zhí)行時(shí)不會(huì)停頓用戶程序的運(yùn)行。

用戶程序在繼續(xù)運(yùn)行,而垃圾收集程序線程運(yùn)行于另一個(gè)CPU上;

如:CMS、G1

安全點(diǎn)與安全區(qū)域

安全點(diǎn)(Safepoint)

程序執(zhí)行時(shí)并非在所有地方都能停頓下來(lái)開始Gc,只有在特定的位置才能停頓下來(lái)開始GC,這些位置稱為“安全點(diǎn)(Safepoint) ”。

Safe Point的選擇很重要,如果太少可能導(dǎo)致Gc等待的時(shí)間太長(zhǎng),如果太頻繁可能導(dǎo)致運(yùn)行時(shí)的性能問(wèn)題。大部分指令的執(zhí)行時(shí)間都非常短暫,通常會(huì)根據(jù)“是否具有讓程序長(zhǎng)時(shí)間執(zhí)行的特征”為標(biāo)準(zhǔn)。比如:選擇一些執(zhí)行時(shí)間較長(zhǎng)的指令作為Safe Point,如方法調(diào)用、循環(huán)跳轉(zhuǎn)和異常跳轉(zhuǎn)等。

如何在GC發(fā)生時(shí),檢查所有線程都跑到最近的安全點(diǎn)停頓下來(lái)呢?

搶先式中斷:(目前沒(méi)有虛擬機(jī)采用了)

首先中斷所有線程。如果還有線程不在安全點(diǎn),就恢復(fù)線程,讓線程跑到安全點(diǎn)。

主動(dòng)式中斷:
設(shè)置一個(gè)中斷標(biāo)志,各個(gè)線程運(yùn)行到safe Point的時(shí)候主動(dòng)輪詢這個(gè)標(biāo)志,如果中斷標(biāo)志為真,則將自己進(jìn)行中斷掛起。

安全區(qū)域(Safe Region)

Safepoint機(jī)制保證了程序執(zhí)行時(shí),在不太長(zhǎng)的時(shí)間內(nèi)就會(huì)遇到可進(jìn)入GC的 Safepoint 。但是,程序“不執(zhí)行”的時(shí)候呢?例如線程處于sleep 狀態(tài)或Blocked狀態(tài),這時(shí)候線程無(wú)法響應(yīng)JVM的中斷請(qǐng)求,“走”到安全點(diǎn)去中斷掛起,JVM也不太可能等待線程被喚醒。對(duì)于這種情況,就需要安全區(qū)域(Safe Region)來(lái)解決。

安全區(qū)域是指在一段代碼片段中,對(duì)象的引用關(guān)系不會(huì)發(fā)生變化,在這個(gè)區(qū)域中的任何位置開始cc都是安全的。我們也可以把safe Region看做是被擴(kuò)展了的safepoint。

實(shí)際執(zhí)行時(shí):

1、當(dāng)線程運(yùn)行到safe Region的代碼時(shí),首先標(biāo)識(shí)已經(jīng)進(jìn)入了Safe Reg如果這段時(shí)間內(nèi)發(fā)生GC,JVM會(huì)忽略標(biāo)識(shí)為Safe Region狀態(tài)的線程;

2、當(dāng)線程即將離開safe Region時(shí),會(huì)檢查JVM是否已經(jīng)完成GC,如果完成了,則繼續(xù)運(yùn)行,否則線程必須等待直到收到可以安全離開safe Region的信號(hào)為止;

再談引用

我們希望能描述這樣一類對(duì)象:當(dāng)內(nèi)存空間還足夠時(shí),則能保留在內(nèi)存中;如果內(nèi)存空間在進(jìn)行垃圾收集后還是很緊張,則可以拋棄這些對(duì)象。

【既偏門又非常高頻的面試題】強(qiáng)引用、軟引用、弱引用、虛引用有什么區(qū)別?具體使用場(chǎng)景是什么?

在JDK 1.2版之后,Java對(duì)引用的概念進(jìn)行了擴(kuò)充,將引用分為強(qiáng)引用(Strong Reference)、軟引用(Soft Reference)、弱引用(Weak Reference)和虛引用( Phantom Reference)4種,這4種引用強(qiáng)度依次逐漸減弱。

除強(qiáng)引用外,其他3種引用均可以在java.lang.ref包中找到它們的身影。如下圖,顯示了這3種引用類型對(duì)應(yīng)的類,開發(fā)人員可以在應(yīng)用程序中直接使用它們。

Reference

Reference子類中只有終結(jié)器引用是包內(nèi)可見的,其他3種引用類型均為public,可以在應(yīng)用程序中直接使用

強(qiáng)引用(StrongReference) :最傳統(tǒng)的“引用”的定義,是指在程序代碼之中普遍存在的引用賦值,即類似“object obj=new object()”這種引用關(guān)系。無(wú)論任何情況下,只要強(qiáng)引用關(guān)系還存在,垃圾收集器就永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象。

軟引用(SoftReference):在系統(tǒng)將要發(fā)生內(nèi)存溢出之前,將會(huì)把這些對(duì)象列入回收范圍之中進(jìn)行第二次回收。如果這次回收后還沒(méi)有足夠的內(nèi)存,才會(huì)拋出內(nèi)存溢出異常。

弱引用(weakReference):被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集之前。當(dāng)垃圾收集器工作時(shí),無(wú)論內(nèi)存空間是否足夠,都會(huì)回收掉被弱引用關(guān)聯(lián)的對(duì)象。

虛引用(PhantomReference):一個(gè)對(duì)象是否有虛引用的存在,完全不會(huì)對(duì)其生存時(shí)間構(gòu)成影響,也無(wú)法通過(guò)虛引用來(lái)獲得一個(gè)對(duì)象的實(shí)例。為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的就是能在這個(gè)對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知。

強(qiáng)引用(StrongReference)不會(huì)回收

強(qiáng)引用(Strong Reference ) ——不回收

在Java程序中,最常見的引用類型是強(qiáng)引用(普通系統(tǒng)99%以上都是強(qiáng)引用),也就是我們最常見的普通對(duì)象引用,也是默認(rèn)的引用類型。

當(dāng)在Java語(yǔ)言中使用new操作符創(chuàng)建一個(gè)新的對(duì)象,并將其賦值給一個(gè)變量的時(shí)候,這個(gè)變量就成為指向該對(duì)象的一個(gè)強(qiáng)引用。

強(qiáng)引用的對(duì)象是可觸及的,垃圾收集器就永遠(yuǎn)不會(huì)回收掉被引用的對(duì)象。

對(duì)于一個(gè)普通的對(duì)象,如果沒(méi)有其他的引用關(guān)系,只要超過(guò)了引用的作用域或者顯式地將相應(yīng)(強(qiáng))引用賦值為null,就是可以當(dāng)做垃圾被收集了,當(dāng)然具體回收時(shí)機(jī)還是要看垃圾收集策略。

相對(duì)的,軟引用、弱引用和虛引用的對(duì)象是軟可觸及、弱可觸及和虛可觸及的,在-定條件下,都是可以被回收的。所以,強(qiáng)引用是造成Java內(nèi)存泄漏的主要原因之一。

強(qiáng)引用例子:

局部變量str指向stringBuffer實(shí)例所在堆空間,通過(guò)str可以操作該實(shí)例,那么str就是stringBuffer實(shí)例的強(qiáng)引用
對(duì)應(yīng)內(nèi)存結(jié)構(gòu):

此時(shí),如果再運(yùn)行一個(gè)賦值語(yǔ)句:

對(duì)應(yīng)內(nèi)存結(jié)構(gòu):

本例中的兩個(gè)引用,都是強(qiáng)引用,強(qiáng)引用具備以下特點(diǎn):

強(qiáng)引用可以直接訪問(wèn)目標(biāo)對(duì)象。
強(qiáng)引用所指向的對(duì)象在任何時(shí)候都不會(huì)被系統(tǒng)回收,虛擬機(jī)寧愿拋出OOM異常,也不會(huì)回收強(qiáng)引用所指向?qū)ο蟆?br /> 強(qiáng)引用可能導(dǎo)致內(nèi)存泄漏。

軟引用(SoftReference)-內(nèi)存不足即回收

軟引用是用來(lái)描述一些還有用,但非必需的對(duì)象。只被軟引用關(guān)聯(lián)著的對(duì)象,在系統(tǒng)將要發(fā)生內(nèi)存溢出異常前,會(huì)把這些對(duì)象列進(jìn)回收范圍之中進(jìn)行第次回收,如果這次回收還沒(méi)有足夠的內(nèi)存,才會(huì)拋出內(nèi)存溢出異常。

軟引用通常用來(lái)實(shí)現(xiàn)內(nèi)存敏感的緩存。比如:高速緩存就有用到軟引用。如果還有空閑內(nèi)存,就可以暫時(shí)保留緩存,當(dāng)內(nèi)存不足時(shí)清理掉,這樣就保證了使用緩存的同時(shí),不會(huì)耗盡內(nèi)存。

垃圾回收器在某個(gè)時(shí)刻決定回收軟可達(dá)的對(duì)象的時(shí)候,會(huì)清理軟引用,并可選地把引用存放到一個(gè)引用隊(duì)列(Reference Queue) 。
類似弱引用,只不過(guò)Java虛擬機(jī)會(huì)盡量讓軟引用的存活時(shí)間長(zhǎng)一些,迫不得已才清理。

在JDK 1.2版之后提供了java.lang.ref.softReference類來(lái)實(shí)現(xiàn)軟引用。

軟引用列子

package com.fs.str;import java.lang.ref.SoftReference;/*** 軟引用列子* -Xms=10m -Xmx=10m*/ public class SoftReferenceTest {public static void main(String[] args) {Object o = new Object();//軟引用SoftReference<Object> objectSoftReference = new SoftReference<Object>(o);o = null;System.gc();//垃圾回收之后獲得軟引用中的對(duì)象System.out.println(objectSoftReference.get());//由于堆空間內(nèi)存足夠,所有不會(huì)回收軟引用的可達(dá)對(duì)象。try {//讓系統(tǒng)認(rèn)為內(nèi)存資源緊張,不夠byte[] b = new byte[ 1024*1024 * 7];} catch ( Throwable e) {e.printStackTrace();} finally {//再次從軟引用中獲取數(shù)據(jù)System.out.println(objectSoftReference.get());//在OOM之前會(huì)回收軟引用的可達(dá)對(duì)象}} }

弱引用(Weak Reference)一發(fā)現(xiàn)即回收

弱引用也是用來(lái)描述那些非必需對(duì)象,只被弱引用關(guān)聯(lián)的對(duì)象只能生存到下一次垃圾收集發(fā)生為止。在系統(tǒng)GC時(shí),只要發(fā)現(xiàn)弱引用,不管系統(tǒng)堆空間使用是否充足,都會(huì)回收掉只被弱引用關(guān)聯(lián)的對(duì)象。

但是,由于垃圾回收器的線程通常優(yōu)先級(jí)很低,因此,并不一定能很快地發(fā)現(xiàn)持有弱引用的對(duì)象。在這種情況下,弱引用對(duì)象可以存在較長(zhǎng)的時(shí)間。

弱引用和軟引用一樣,在構(gòu)造弱引用時(shí),也可以指定一個(gè)引用隊(duì)列,當(dāng)弱引用對(duì)象被回收時(shí),就會(huì)加入指定的引用隊(duì)列,通過(guò)這個(gè)隊(duì)列可以跟蹤對(duì)象的回收情況。

軟引用、弱引用都非常適合來(lái)保存那些可有可無(wú)的緩存數(shù)據(jù)。如果這么做,當(dāng)系統(tǒng)內(nèi)存不足時(shí),這些緩存數(shù)據(jù)會(huì)被回收,不會(huì)導(dǎo)致內(nèi)存溢出。而當(dāng)內(nèi)存資源充足時(shí),這些緩存數(shù)據(jù)又可以存在相當(dāng)長(zhǎng)的時(shí)間,從而起到加速系統(tǒng)的作用

在DK 1.2版之后提供了java.lang.ref.weakReference類來(lái)實(shí)現(xiàn)弱引用

弱引用對(duì)象與軟引用對(duì)象的最大不同就在于,當(dāng)GC在進(jìn)行回收時(shí),需要通過(guò)算法檢查是否回收軟引用對(duì)象,而對(duì)于弱引用對(duì)象,GC總是進(jìn)行回收。弱用對(duì)象更容易、更快被GC回收。

面試題:你開發(fā)中使用過(guò)weakHashMap嗎?

由于weakHashMap就是若引用,所以開發(fā)中使用這個(gè)會(huì)即使回收

虛引用(Phantom Reference)—對(duì)象回收跟蹤

也稱為“幽靈引用”或者“幻影引用”,是所有引用類型中最弱的一

一個(gè)對(duì)象是否有虛引用的存在,完全不會(huì)決定對(duì)象的生命周期。如果一個(gè)對(duì)象僅持有虛引用,那么它和沒(méi)有引用幾乎是一樣的,隨時(shí)都可能被垃圾回收器回收。

它不能單獨(dú)使用,也無(wú)法通過(guò)虛引用來(lái)獲取被引用的對(duì)象。當(dāng)試圖通過(guò)虛引用的get()方法取得對(duì)象時(shí),總是null。

為一個(gè)對(duì)象設(shè)置虛引用關(guān)聯(lián)的唯一目的在于跟蹤垃圾回收過(guò)程。比如:能在這個(gè)對(duì)象被收集器回收時(shí)收到一個(gè)系統(tǒng)通知。

虛引用必須和引用隊(duì)列一起使用。虛引用在創(chuàng)建時(shí)必須提供一個(gè)引用隊(duì)列作為參數(shù)。當(dāng)垃圾回收番人爸引Y一入A用隊(duì)列,以通知應(yīng)用程序?qū)ο蟮木蜁?huì)在回收對(duì)象后,將這個(gè)虛引用加入引用隊(duì)列,以通知應(yīng)用程序?qū)ο蟮幕厥涨闆r。

由于虛引用可以跟蹤對(duì)象的回收時(shí)間,因此,也可以將一些資源釋放操作放置在虛引用中執(zhí)行和記錄。

在JDK 1.2版之后提供了PhantomReference類來(lái)實(shí)現(xiàn)虛引用。

終結(jié)器引用

它用以實(shí)現(xiàn)對(duì)象的finalize ()方法,也可以稱為終結(jié)器引用。
無(wú)需手動(dòng)編碼,其內(nèi)部配合引用隊(duì)列使用。
在Gc時(shí),終結(jié)器引用入隊(duì)。由Finalizer線程通過(guò)終結(jié)器引用找到被引用對(duì)象并調(diào)用它的finalize ()方法,第二次cc時(shí)才能回收被引用對(duì)象。

總結(jié)

以上是生活随笔為你收集整理的JVM学习笔记之-垃圾回收相关概念 System.gc()的理解 内存溢出与内存泄漏 STW 垃圾回收的并行与并发 安全点与安全区域 再谈引用:强引用 软引用 弱引用 虚引用 终结器引用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。