Java編程開發之淺析Java引用機制

對於一個Java的對象而言,存儲主要分爲兩種,一種是內存堆(Heap),內存堆是無序的,主要用來存放創建的Java對象;一種是內存棧(Stack),主要用來存放Java引用,然後在管理過程使用Java引用指向Java對象。

關於Reference引用的“那些事兒"

BW1nxS.jpg

隨着黃金梅麗號在大海之上的飄蕩,一切看着是那麼的風平浪靜,但是每個人似乎都在忙着自己手裏的那些事情....突然韋柏向薩博提出了一個問題:都知道JVM調優是當下從事Java開發必須要去具備甚至要去提升自己的一個重要環節,那你知道堆與棧,各自存放機制是什麼?也就針對於這個問題,就像當初去探索世界盡頭的夢想一樣,薩博這樣回答韋柏:對於一個Java的對象而言,存儲主要分爲兩種,一種是內存堆(Heap),內存堆是無序的,主要用來存放創建的Java對象;一種是內存棧(Stack),主要用來存放Java引用,然後在管理過程使用Java引用指向Java對象。 聽完薩博的回答,韋柏靠在甲板上,點燃了一支猩紅的香菸,抽了一口,然後對薩博說道:那你能詳細的講解一下這個引用機制麼?薩博思考了一下,於是有了以下的故事.......

GC[Garbage Collectors]的基本原理

s58VjP.png

在引入Reference引用的概念之前,我們需要清楚的知道內存棧(Stack)和內存堆(Heap)在JVM虛擬機的結構分佈以及基本情況,如上圖所示。綜上所述,我們可以瞭解到Java的內存管理實際上就是對象的管理,包括對象實例的分配和釋放。其中GC的存在就是負責在對象“不可達”的時候將對象回收處理。當系統在創建對象實例的時候,即當使用new關鍵字創建一個對象的時候,GC就開始監控對象的地址、大小以及使用狀態。一般情況下,Java的GC機制都有特定的回收算法,GC通常會使用有向圖的方式來記錄隊中的所有對象,通過此種方式確定甚至標記哪些對象是“可達的”,而哪些是“不可達的”。當GC判斷一些對象不可達的時候,GC就有責任回收相關內存空間,是否能被垃圾回收機制回收,具體操作是取決於機器和平臺,但判斷依據主要是看對象是否有引用指向該對象。

Reference引用基本概述

Abstract base class for reference objects. This class defines the operations common to all reference objects. Because reference objects are implemented in close cooperation with the garbage collector, this class may not be subclassed directly.

不難發現,Reference機制對JVM的垃圾收集活動敏感,Reference的繼承關係或者實現是由JDK定製,引用實例是由JVM創建,一般不推薦自行繼承Reference實現自定義的引用類型,但是可以繼承已經存在的引用類型。
JDK提供了強引用(Strong Reference)、軟引用(Soft Reference)、弱引用(Weak Reference)和虛引用(Phantom Reference),引用隊列(ReferenceQueue)以及析構引用(Final Reference)等引用類型。

[⚠️注意事項]:

  1. 強引用可能對垃圾收集活動是不敏感的
  2. 自行繼承Reference實現自定義的引用類型,其反覆造輪子的意義不大。
  3. 析構引用(Final Reference),它是一種特化的虛引用
  4. 不同JDK版本,需要注意實際源碼的對比分析。
    5.Reference是所有引用對象的基類

Reference引用類型分析

s4EtN8.png

強引用(Strong Reference):在Java中最常見的就是強引用,也是最普遍存在的引用類型。處於可達狀態,是不可能被垃圾回收機制回收的,即使該對象以後永遠都不會被用到JVM也不會回收。

軟引用(Soft Reference):對於只有軟引用的對象來說,當系統內存足夠時它不會被回收,當系統內存空間不足時它會被回收。軟引用通常用在對內存敏感的程序中。

弱引用(Weak Reference):比軟引用的生存期更短,對於只有弱引用的對象來說,只要垃圾回收機制一運行,不管JVM的內存空間是否足夠,總會回收該對象佔用的內存。
虛引用(Phantom Reference):不能單獨使用,必須和引用隊列聯合使用。虛引用的主要作用是跟蹤對象被垃圾回收的狀態。
引用隊列(ReferenceQueue)
析構引用(Final Reference)

[⚠️注意事項]:

  1. 強引用可能對垃圾收集活動是不敏感的,沒有對應的類型表示,也就是說強引用是普遍存在的,如Object object = new Object();。
  2. 軟引用、弱引用和虛引用都是java.lang.ref.Reference的直接子類。
  3. 直到JDK11爲止,只存在四種引用,這些引用是由JVM創建,因此直接繼承java.lang.ref.Reference創建自定義的引用類型是無效的,但是可以直接繼承已經存在的引用類型,如java.lang.ref.Cleaner就是繼承自java.lang.ref.PhantomReference。
  4. 特殊的java.lang.ref.Reference的子類java.lang.ref.FinalReference和Object#finalize()有關,java.lang.ref.Finalizer是java.lang.ref.FinalReference子類。
    版權聲明:本文爲博主原創文章,遵循相關版權協議,如若轉載或者分享請附上原文出處鏈接和鏈接來源。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章