熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

銷毀對象的三把利劍

2022-06-13   來源: Java核心技術 

  在任何一個面向對象的語言中這個對象銷毀機制都是很重要的因為如果對象不能夠被及時的回收那麼很多沒用的對象就仍然會占用內存地址久而久之就會導致內存耗竭從而導致服務器當機

  在這個對象的銷毀上Java語言比其他面向對象的語言更勝一籌因為其他面向對象的語言需要在程序代碼中手工回收廢棄的對象不過Java語言則不同在Java語言中擁有一套完整的對象垃圾回收機制即程序開發人員不需要手工的回收廢棄的對象垃圾回收器將回收無用對象所占用的內存資源不過這個垃圾回收器並不是萬能的需要結合其他的對象回收方式才能夠最終解決這個對象回收的問題在Java中總共有三種方式可以用來解決對象回收的問題筆者將他們稱為三把利劍

  第一把劍垃圾回收器

  垃圾回收器是Java平台中用的最頻繁的一種對象銷毀方法垃圾回收器會全程偵測Java應用程序的運行情況當反先有些對象成為垃圾時垃圾回收器就會銷毀這些對象並釋放這些對象所占用的內存空間在這裡程序開發人員需要知道在哪些情況下垃圾回收器會認為這些對象是垃圾對象通常情況下如果發生以下兩種情況時系統會認為這些對象是垃圾對象需要銷毀

  一是將一個NULL值賦值給對象如用戶先建立了一個對象str對象用完了之後再利用賦值語句將NULL值賦值給這個對象str即使用str=NULL的方式將NULL值賦值給這個對象此時這個對象與內存中對象的存儲地址之間就失去了聯系此時內存中的對象就好像成為了一個無主的對象就會被垃圾回收器銷毀不過這也有例外如現在同一個對象有兩個名字分別為str與str此時若只是將NULL值賦值給str那麼內存的這個對象仍然有一個主人即str此時這個對象還暫時不會被垃圾回收器回收除非在代碼中講這個對象所關聯的所有對象名字都賦值為NULL此時這個對象才變為無主的對象才會被垃圾回收器回收在Java中定義自己的工具庫

  二是對象其超出了作用范圍這個這個對象就被認為是垃圾對象被被垃圾回收器回收並釋放內存其實對象跟變量一樣其也有作用域當超過這個作用域的話跟變量一樣這個對象也就無效了其他地方不能夠再引用這個對象此時這個對象就是名存實亡了為此垃圾回收器也把這種超過作用范圍的對象當作垃圾對象來處理所以說如果程序員要讓對象中的某些成員變量或者成員方法一直有效的話就需要采用static關鍵字讓其在變量銷毀時仍然有效或則仍然可以調用這些成員變量與成員方法

  另外筆者在這裡各位讀者一個小的思考題大家想想看如果遇到如下這種情況Java垃圾回收器是否會回收對象?現在筆者先定義兩個對象strstr此時在內存中已經為這個兩個對象分配了存儲空間然後筆者再利用str=str語句將str指向的內存地址賦值給str此時對象strstr就指向同一個內存地址即代表同一個對象而原先對象str指向的對象就變成了一個無主的對象了對象名str已經與這個對象失去了聯系在這種情況下這個對象是否會被當作垃圾對象被銷毀呢?給為讀者回去可以好好想想這個問題若能夠得出正確的答案則說明大家對於垃圾回收器已經有了比較透徹的了解  JDK更新為Java帶來更多模塊

  第二把利劍finalize方法

  雖然說垃圾回收器已經是一個比較完善的對象銷毀機制但是其並不能夠解決Java語言中所有對象的銷毀問題如Java語言平台中創建對象主要有兩種方式分別為利用NEW關鍵字來創建(這是對象創建的主要方式)與不適利用NEW關鍵字來創建如果Java語言中某些對象不是利用new關鍵字為對象在內存中分配一塊存儲區域那麼這種類型的對象就不能夠被垃圾回收站回收即使在代碼中將NULL值賦值給這個對象仍然不能夠被垃圾回收器回收雖然這種對象比較少但是畢竟存在為了解決這類對象的回收與內存釋放問題在Java語言中提供了一個finalize的方法通過這個方法可以顯示的讓系統回收這個對象這是一個Object類的方法通常情況下這個方法是被聲明為protected程序開發人員在必要的時候可以在自定的類中定義這個方法假設現在程序開發人員定義了這個方法那麼在對象銷毀時垃圾回收器會先采用這個方法來銷毀對象並且在下一次垃圾回收動作發生時最終釋放對象的內存

  可見采用了finalize 方法雖然可以讓這個對象被垃圾回收器回收但是其原理是不同的垃圾回收器是先調用這個方法然後在下次運行這個垃圾回收作業時再釋放其占用的內存另外需要注意的是這個方法並不一定會保證發生也就是說相對來講其安全性並沒有垃圾回收器那麼的高故在實際創建對象時最好還是采用new關鍵字來創建比較安全也更加的方便因為在利用New關鍵字來創建對象時在代碼中不需要加入另外額外的代碼所以從安全性與便利性上來說筆者都建議采用new方法為對象在內存中分配存儲區域而不建議采用其他的方式在采用垃圾回收器的時候其會自動檢測對象的狀態而不需要程序員告知其發現對象超出了作業域范圍或者對象被重置為空時其就會被自動銷毀並釋放對象所占用的內存這種方式處理起來相對來說更加的安全與便利

  第三把利劍利用Systemgc方法強制啟動垃圾回收器

  垃圾回收器其實自動啟動的也就是說垃圾回收機制起會自動監測垃圾對象並在適當的時候啟動垃圾回收器來銷毀對象釋放內存但是這個垃圾回收器也會有不合作的時候也就是說這個垃圾回收器不受程序代碼的控制其具體執行的時間也會不確定從而導致上面的finalize方法無法執行某些對象無法及時銷毀為此有時候需要利用代碼來強制啟動垃圾回收器來銷毀對象

  筆者平時在給一些學員培訓時往往將這個垃圾回收器比喻成醫院裡的護士平時的時候護士會每隔一段時間來進行查房看看病人有沒有什麼問題不過在必要的時候病人也可以通過警鈴來呼叫護士如當鹽水掛完了就可以要求護士來更換鹽水其實這個護士定期查房就好像是垃圾回收器會根據應用程序的運行情況來定時的或者不定時的啟動而這個警鈴就好像是這個Systemgo方法在有需要的時候程序開發人員可以在代碼中調用這個方法來強制讓護士來病房即強制啟動這個垃圾回收器采用這個方法給程序開發人員多了一種主動權而不需要被動的等著垃圾回收器的啟用有時候在代碼種類利用這個方法不定期或者定期的強制啟動垃圾回收器對及時銷毀垃圾對象能夠起到一個輔助與保障作用


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25764.html
    推薦文章
    Copyright © 2005-2022 電腦知識網 Computer Knowledge   All rights reserved.