java 內存 四_java最終化的內存保留問題(4)

四、

一種代替最終化的選擇

在前面一節中的示例還存在一種不確定性可能:JVM并不能保證它在最終化隊列中調用對象的終結器的順序。而來自于所有類(應用程序,庫,等等)的終結器都是被同等對待的。因此,一個占有大量內存或一種稀有的本地資源的對象可能受阻于終結化隊列-它們排在那些終結器進度緩慢的對象之后(不一定是惡意;也許由于懶惰的編程所致)。

看完上面達內培訓老師分享的的第一段內容之后大家是不是已經知道今天我們要為大家分享什么內容了那?

為了避免這種類型的不確定性,你可以使用弱參考來代替最終化,例如使用死后鉤子(postmortem

hook)。如果用這種方式,你可以完全控制怎樣優先化本地資源的回收問題,而代替依賴于JVM完成這件事情。下面的示例展示了這一技術:

final

class NativeImage3 extends WeakReference {

private

int nativeImg;//指向本地圖像數據

//它釋放本地圖像;隨后對它的調用將被忽略

private

native void disposeNative();

void

dispose() {

disposeNative();

refList.remove(this);

}

static

private ReferenceQueue refQueue;

static

private List refList;

static

ReferenceQueue referenceQueue() {return refQueue;}

NativeImage3(Image3

img) {

super(img,

refQueue);

refList.add(this);

}

}

public

class Image3 {

private

NativeImage3 nativeImg;

private

Point pos;

private

Dimension dim;

public

void dispose() { nativeImg.dispose(); }

}

Image3與Image2相同。NativeImage3相似于NativeImage2,但是它的最后清理依賴于弱參考而不是最終化。NativeImage3擴展WeakReference,其參考是與之相關聯的Image3實例。請記住,當一個參考對象的參考(此時是WeakReference)成為不可達的時,該參考對象就被添加到與之相關聯的參考隊列上。把nativeImg嵌入到參考對象本身就保證JVM會正確地把所需要的加入到隊列中(見圖6)。再強調一下,NativeImage3不應該成為Image3的一個子類,這是基于前面所述原因。

圖6.把nativeImg嵌入到Reference對象本身

你可以決定是否一參考對象的參考物已經被垃圾收集器以兩種方式回收:顯式地,在參考對象上調用get()方法;隱式地,通過觀察參考對象已經在相關聯的參考隊列中排隊來實現。本示例中只使用了后者。

注意,參考對象僅能被垃圾收集器所發現并且被添加到它們的相關聯的參考隊列-只有它們本身是可達的時候。否則,它們就象任何其它不可達的對象一樣被簡單地回收。這就是為什么你把所有的NativeImage3實例添加到該靜態鏈表(實際上,任何數據結構都會滿足):為了確保它們保持為可達的并且當它們的參考物成為不可達的時被處理。當然,你還必須確保當你釋放它們時(這是通過dispose()方法來實現的)你從該列表中刪除了它們。

當在一個Image3實例上顯式地調用dispose()方法時,在該實例上不會發生隨后的最后清理;正確情況下也是這樣,因為這里不需要任何東西。這個dispose()方法從靜態列表中刪除NativeImage3實例,這樣當它的相應的Image3實例成為不可達的時它就是不可達的。并且,如前所述,不可達的參考對象并不被添加到它們相應的參考隊列。相反,在所有前面的使用了最終化的示例中,可最終化的對象將總是被作最終化考慮-當它們成為不可達的時候,無論你是否已顯式地釋放它們相關聯的本地資源。

JVM將保證,當通過垃圾收集器發現一個Image3實例是不可達的時候,它會把它的相應的NativeImage3實例添加到它的相關聯的參考隊列上去。然后,由你負責把它從隊列中刪除并釋放它的本地資源。這可以通過在一個"清理"線程中,用一個如下的循環來實現:

ReferenceQueue

refQueue =NativeImage3.referenceQueue();

while

(true) {

NativeImage3

nativeImg =(NativeImage3) refQueue.remove();

nativeImg.dispose();

}

這是一個過于簡單的實例。高級開發者能另外根據它們如何需要優先化清理來確保不同參考對象關聯于不同的參考隊列。并且一個單個的"清理"線程可以查詢所有可用的參考隊列和根據要求的優先級來從隊列中刪除對象。另外,你可以選擇展開(spread

out)回收資源,這樣它就會給應用程序帶來更少的危險性。

盡管用這種方式清理資源與使用最終化相比,明顯是更復雜些,但是這也是一種更為有力量和更為靈活的方式,而且可以最小化大量的與使用最終化相關的不確定性。另外,這種方式還十分相似于最終化實際在JVM內實現的方式。對于那些顯式地使用很多本地資源并且需要更多控制的工程,我推薦對它們進行清理時使用這一方法。而只要小心地使用最終化對于大多數另外的工程來說也就足夠了。

注意:本文僅討論了兩種類型的在使用最終化時產生的問題,也就是內存和資源保留問題。最終化和參考類的使用也能帶來很微妙的同步問題。要想詳細了解這一點,可以參考Read

Hans-J.Boehm的《最終化,線程和基于Java技術的內存模型》一文。

五、僅在必要時才使用最終化

本文簡短描述了最終化是怎樣在JVM中實現的。然后給出了有關內存是怎樣不必被可最終化的對象所保留的示例并且概括了這種問題的解決方案。最后,我描述了一個方法-它使用弱參考來代替-這允許你用一種更為靈活和可預測的方式來執行最后清理。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/537986.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/537986.shtml
英文地址,請注明出處:http://en.pswp.cn/news/537986.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Spring Boot不同的環境使用不同的配置方法

原文路徑:http://www.jb51.net/article/132589.htm ---------------------------------------- 默認是profile為dev,可以修改 spring 多文件配置: 1、properties文件 2、YAML文件 一、properties文件 在 Spring Boot 中, 多環境配…

java set方法賦值_java方面:private屬性,沒有set方法,只有get方法,如何給這個屬性賦值?...

富國滬深用反射吧,然后設置setAccessible為true就可以了,如下:public class Test {private String readOnly;public String getReadOnly() {return readOnly;}public static void main(String[] args) throws SecurityException, NoSuchField…

SpringBoot項目在IntelliJ IDEA中實現熱部署

spring-boot項目熱部署idea工具&#xff1a; &#xff08;1&#xff09;、pom文件引入&#xff1a;都需要為true<!-- 熱部署模塊 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId…

java nio 對消息分片_Java NIO:應用

Java NIO 是一種非阻塞的、面向塊而非字節的 IO 方式。雖然 Java 的傳統 IO 也進行了一些基于 NIO 的改造&#xff0c;NIO 仍然能夠帶來許多優勢。面向流的 IO 方便我們一個字節一個字節地處理數據&#xff0c;有利于實現過濾等功能&#xff0c;更加優雅和簡單。相應地&#xf…

使用Notepad++來比較文件

原文連接&#xff1a;https://blog.csdn.net/sanqima/article/details/50467154 -----------------------------------------------------------------------------Notepad&#xff0c;也叫npp&#xff0c;是一款類似于記事本的開源小軟件。它運行便攜&#xff0c;體積小、資源…

利用lamda函數 的函數式編程 實現scrapy審計外網安全問題

2019獨角獸企業重金招聘Python工程師標準>>> import scrapy from scrapy.spiders import Spiderdef parse_response(response, ip_in):title response.xpath("/html/head/title").extract()[0]filename quotes.txtwith open(filename, a) as f:f.write(…

Linux服務器上新增開放端口號

原文連接&#xff1a; https://blog.csdn.net/u012562106/article/details/52882666 ---------------------------------------開放端口的方法&#xff1a; 方法一&#xff1a;命令行方式 1. 開放端口命令&#xff1a; /sbin/iptables -I INPUT -p tcp --dport 8…

return ,continue,break的用法與區別總結

1、return 語句的作用 (1) return 從當前的方法中退出,返回到該調用的方法的語句處,繼續執行。 (2) return 返回一個值給調用該方法的語句&#xff0c;返回值的數據類型必須與方法的聲明中的返回值的類型一致&#xff0c;可以使用強制類型轉換來是數據類型一致。 (…

linux java -xms_為什么JVM比指定的-Xms消耗更少的內存?

我的問題是 Headers &#xff0c;我通過搜索獲得了一些知識&#xff1a;但還是不知道為什么&#xff0c;有些可以提供一些幫助嗎&#xff1f;這是我在Ubuntu12.04(64位)上的測試運行JDK 1.7.0_04 . 和頂部顯示如下&#xff1a;PID USER PR NI VIRT RES SHR S %CPU %MEM TIME CO…

Jquery的一些方法

$.trim(str);說明&#xff1a;去掉字符串首尾空格。轉載于:https://www.cnblogs.com/gygtech/p/9552538.html

清除nginx服務器網站緩存數據

原文連接&#xff1a;https://blog.csdn.net/Crabime/article/details/51883028?locationNum2&fps1 -------------------------------------公司網站上線之后后面老是出現一些小的bug&#xff0c;但是這些bug在vi上改了之后打開更改的網頁卻發現并沒有更改&#xff0c;goo…

linux安裝指定版本python_ubuntu多版本python為指定版本python安裝庫

當安裝了多個版本的Python時&#xff0c;比如一個python2.7&#xff0c;一個python3.5&#xff0c;需要為某個python版本安裝庫時如何精準的指定python版本呢。網上多數回答都是用到pyenv、virtualenv之類&#xff0c;看了下感覺跟我的預期不一致。因為PyCharm已經可以管理多個…

Linux 如何通過某一臺服務器調用執行多臺遠程服務器上的腳本,結果顯示在本地?...

現在都流行自動化運維了&#xff0c;可能目前技術不夠&#xff0c;很多自動化工具還不怎么會用&#xff0c;所以本次只是通過ssh來實現功能。 說明&#xff1a;自己寫的一個簡單腳本&#xff0c;只是實現了基礎功能&#xff0c;還有待優化。 一共三臺機器&#xff1a; master&a…

linux下查看磁盤分區的文件系統格式

原文鏈接&#xff1a; https://www.cnblogs.com/youbiyoufang/p/7607174.html ------------------------------------------------------------------------- df -T 只可以查看已經掛載的分區和文件系統類型。 Filesystem Type 1K-blocks Used Available Use% Mounted on/dev/s…

ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)

Linux下mysql的安裝&#xff0c;真是不同Linux環境&#xff0c;各種問題。步驟&#xff1a; 1、暫停mysql服務 service mysqld stop2、設置mysql模式# mysqld_safe --usermysql --skip-grant-tables --skip-networking & 3、clone session&#xff0c;新窗口# mysql -u roo…

mysql 跳表 b 樹_簡單談談Mysql索引與redis跳表

摘要面試時&#xff0c;交流有關mysql索引問題時&#xff0c;發現有些人能夠濤濤不絕的說出B樹和B樹&#xff0c;平衡二叉樹的區別&#xff0c;卻說不出B樹和hash索引的區別。這種一看就知道是死記硬背&#xff0c;沒有理解索引的本質。本文旨在剖析這背后的原理&#xff0c;歡…

(Ajax)axios源碼簡析(三)——請求與取消請求

傳送門&#xff1a; axios源碼簡析&#xff08;一&#xff09;——axios入口文件axios源碼簡析&#xff08;二&#xff09;——Axios類與攔截器axios源碼簡析&#xff08;三&#xff09;——請求與取消請求請求過程 在Axios.prototype.request中我們看到&#xff0c;要先通過請…

Windows配置tomcat環境

1、安裝JDK 參考教程&#xff1a; https://jingyan.baidu.com/article/6dad5075d1dc40a123e36ea3.htmlCLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jarCLASSPATH這個環境變量一定要配好&#xff0c;否則tomcat起不來&#xff0c;直接復制上面的內容&#xff0c;…

java 抽獎 高并發處理_如何設計高并發下的抽獎?

關于抽獎,需要考慮的點有很多,這里稍微整理了下主要需要考慮以下三點:用戶抽獎次數限制獎品數量限制獎品發放的分布中獎的概率的可控性用戶抽象次數限制一個用戶必須限制抽獎的次數,而同一個用戶的并發幾率其實是很小的,所以這里可以用悲觀鎖來控制用戶的抽獎次數。獎品數量限制…

WPF圓角按鈕與觸發顏色變化

原文:WPF圓角按鈕與觸發顏色變化<Button x:Name"button1" Content"按鈕1" Margin"10,10,0,0" Cursor"Pen"><Button.Template><ControlTemplate><Border CornerRadius"15,15,15,15"><Border.Back…