您好,登錄后才能下訂單哦!
今天就跟大家聊聊有關如何解析Java對象引用與JVM自動內存管理,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。
解析Java對象引用與JVM自動內存管理(轉)[@more@]對象引用應用程序設計接口是JDKTM1.2中新定義的。該應用程序設計接口允許應用程序以對象引用的方式與JVM的內存管理器進行交互。當應用程序需管理大量內存對象或者在新的Java對象創建之前需刪除原有對象時,Java對象引用應用程序設計接口具有相當大的用途,例如:
● 基于Web的應用程序常常要求顯示大量圖片,當用戶離開某一Web頁時,往往不能確定是否能夠順利的返回。在這種程序中,應用Java對象引用API可以創建這樣一個環境,即當堆內存以最小程度運行時,內存管理器創建對象。當用戶返回時,應用程序就會重新載入已經創建的圖片。
● 應用對象引用隊列可以創建這樣一個環境,當通過對象引用獲得某一對象時,應用程序得到通知。然后,應用程序就可以對相關對象進行清除操作,同時使這些對象在內存管理器中合法化。
內存管理器的工作機制
下面將首先介紹未嵌入引用對象時內存管理器的工作機制,然后討論引用對象加入之后Java堆發生的變化。
內存管理器的作用就是識別程序中不再使用的對象,并且回收其內存。
一個Java應用程序由一系列線程組成,每個線程執行一系列方法,而每個方法通過參數或局部變量來引用對象。這些引用屬于引用集合中的一部分,直接進入應用程序。另外,引用集合中還包括類庫中定義的靜態引用變量,以及通過Java本地接口(JNI)API獲得的引用。引用集合中的所有引用對象都可以被當前應用程序獲取,而不必被回收。同樣地,這些對象可能包含對其它對象的引用,也可以被應用程序獲取,依此類推。Java堆中的其它對象視為不可獲取的,而所有這些不可獲取的對象在內存管理中也是合法的。如果一個不可獲取的對象使用finalize()方法,任務就交給了對象所調用的收尾器(finalizer)。在內存回收期間,不具有收尾器的不可獲取對象和已經調用收尾器的對象被簡單回收。
內存回收的算法是不斷變化的,共性的方面是從引用集合中識別可獲取的對象以及回收被其它對象占據的內存空間。
加入引用對象之后的引用與常規引用的區別在于,引用對象中的引用專門由內存管理器來處理。引用對象封裝了其它一些對象的引用,我們稱之為指示對象。在引用對象創建的同時,也就定義了該引用對象的指示對象。
根據應用程序要求,對象可以是強引用(strong references)、次引用(soft references)、弱引用(weak references)、虛引用(phantom references)的任意組合。為了確定對象的可獲取程度,JVM內存管理器從引用集合出發遍尋堆中所有到對象的路徑。當到達某對象的任意路徑都不含有引用對象時,則稱該對象具有強獲取能力;當路徑中含有一個或幾個引用對象時,根據內存管理器所查詢的引用對象的類型分別歸為次獲取、弱獲取、虛獲取。
另外,對象引用API中還定義了引用對象隊列(java.lang.ref.ReferenceQueue),這是內存管理器對引用對象進行管理的一種簡單數據結構。值得注意的是,在進行引用對象定義時,要求phantom reference對象必須產生于一個引用對象隊列,而soft reference和weak reference對象則無此限制,如:
ReferenceQueue queue = new ReferenceQueue();
PhantomReference pr = new PhantomReference(object, queue);
Soft References 應用實例
下面以在基于web的應用程序中使用soft references為例,來說明Java對象引用與JVM的內存管理器進行交互的原理。
當用戶打開某一web頁時,applet代碼獲得圖片并且得到顯示。如果在代碼中同時創建了該圖片對象的soft references,那么當用戶離開該web頁時,內存管理器對圖片所分配的內存是否回收做出選擇。當用戶返回該web頁時,在applet代碼中使用SoftReference.get方法就會得到圖片才內存中是否仍存在的消息。如果在內存管理器中未創建該圖片,在web頁上會很快得到顯示;否則,applet代碼就會重新獲取。
下面是Example.java的完整源代碼。
import java.awt.Graphics;import java.awt.Image;import java.applet.Applet;import java.lang.ref.SoftReference;public class Example extends Applet { SoftReference sr = null; public void init() { System.out.println("Initializing"); } public void paint(Graphics g) { Image im = (sr == null) ? null : (Image)(sr.get()); if (im == null) { System.out.println("Fetching image"); im = getImage(getCodeBase(),"yundong.gif"); sr = new SoftReference(im); } System.out.println("Painting"); g.drawImage(im, 25, 25, this); g.drawString("運動之美",20,20); im = null; /* Clear the strong reference to the image */ } public void start() { System.out.println("Starting"); } public void stop() { System.out.println("Stopping"); }}
在上面的代碼中,對象image是一個圖片對象,傳遞給一個SoftReference對象sr。其中image對象是sr的指示對象,sr中的引用域是從次引用(soft reference)到 image。
Weak References分析
對于一個穩定的對象,比如說線程類對象,當需要獲取外部數據時,在程序中應用weak references是非常理想的。如果利用引用隊列創建了某一線程的weak reference,那么當線程不再具有強獲取能力時,應用程序得到通知,根據此通知,應用程序才能執行相關數據對象的清除工作。
當內存管理器未發現strong references 和 soft references 時,我們稱對象具有弱獲取能力,即在到達該對象的路徑中至少包含一個weak reference。程序中weak references被清除一段時間后,弱獲取對象被收尾器收集。由此也可以看出,soft reference和weak reference之間的區別在于,應用soft reference時,內存管理器利用算法決定是否創建弱獲取對象,而應用weak reference時,內存管理器必須創建次獲取對象。
引用對象鏈
當到達某一對象的路徑中含有多個引用對象時,就構成了引用對象鏈。內存管理器按照由強到弱的順序處理引用對象,具體處理步驟包括:Soft references、 Weak references、Finalization、Phantom references和創建對象五個部分。
當內存管理器未發現前三種對象引用時,我們稱對象具有虛獲取能力,即在到達該對象的路徑中至少包含一個phantom reference。虛引用對象直接被收尾器收集,而不被重新創建。當內存管理器發現只有phantom references時,對象就將處于等候phantom reference狀態,應用程序向引用隊列發出通知,然后對虛引用對象調用clear()方法,將其引用域設置為null,最后對不可獲取對象執行收集清除處理任務。
通常,對象所具有的獲取能力與引用對象集合直接路徑中的最弱連接者相同。據此可以看出:
虛引用對象具有強獲取能力,其它對象均具虛獲取能力;
(b)中虛引用對象和弱引用對象均具強獲取能力,故次引用對象和對象集合具有若獲取能力;
(c)中虛引用對象、弱引用對象和次引用對象均具強獲取能力,那么對象集合則具次獲取能力。
● 在程序中使用引用對象API不但可以在一定程度上控制內存管理器,實現內存自動管理,還可以提高程序的穩定性和安全性。
● 引用對象鏈中各個對象的獲取能力與整個鏈相關。
看完上述內容,你們對如何解析Java對象引用與JVM自動內存管理有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。