您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關如何解析關于Java垃圾回收的問題,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
Java垃圾回收器只知道釋放那些經由new分配的內存,所以它不知道該如何釋放該對象的這塊"特殊"內存.為了應對這種情況,Java允許在類中定義一個名為finalize()的方法.它的工作原理"假定"是這樣的:一旦Java垃圾回收器準備好釋放對象占用的存儲空間,將首先調用其finalize()方法.并且在下一次垃圾回收動作發生時,才會真正回收對象占用的內存.所以要是你打算用finalize(),就能在垃圾回收時刻做一些重要的清理工作.也許你會發現,只要程序沒有瀕臨豐儲空間用完的那一刻,對象占用的空間就總也得不到釋放,如果程序執行結束,并且垃圾回收器一直沒有釋放你創建的任何對象的存儲空間,則隨著程序的退出,那些資源也會全部交還給操作系統.
這個策略是恰當的,因為垃圾回收本身也有開銷,要是不使用它,那就不用支付這部分開銷.所以你根本沒有辦法知道垃圾回收器會不會執行,什么時候執行.你要回收的對象不一定會被回收.finalize()方法用于清理什么樣的對象?如果我要清理某個對象,而該對象中含有其它對象,finalize()就應該明確釋放那些對象呢?
不----無論對象是如何創建的,Java垃圾回收器都會負責釋放對象占據的所有內存.這就將對finalize()的需求限制到一種特殊情況,即通過某種創建對象方式以外的方式為對象分配存儲空間.不過,大家也看到,Java中一切皆為對象,那這種特殊情況是怎么回事?看來之所以要有finalize(),是由于在分配內存時可能采用了類似C語言中的做法.而非Java中的通常做法.
這種情況主要發生在使用"本地方法"的情況下,本地方法是一種在Java中調用非Java代碼的方式.本地方法目前只支持C和C++,但它們可以調用其他語言寫的代碼,所以實際上可以調用任何代碼.在非Java代碼中,也許會調用C的malloc()函數系列來分配存儲空間,而且除非調用了free()函數,否則存儲空間將得不到釋放,從而造成內存泄露.當然,free()是C和C++中的函數,所以要在finalize()中用本地方法調用它.至此,大家或許明白了不要過多地使用finalize()的道理了.System.gc(),強行運行垃圾回收器.
finalize()在什么時候被調用?有三種情況1.對象被Garbage Collection時自動調用,比如運行System.gc()的時候.2.程序退出時為每個對象調用一次finalize方法。3.顯式的調用finalize方法
除此以外,正常情況下,當某個對象被系統收集為無用信息的時候,finalize()將被自動調用,但是jvm不保證finalize()一定被調用,也就是說,finalize()的調用是不確定的,這也就是為什么sun不提倡使用finalize()的原因.
測試代碼 package test;
/** * 測試垃圾回收器與finalize()方法 * @author Administrator */ public class GcTest { public static void main(String[] args) { Book b1 = new Book(); b1.setName("new"); Book b2 = new Book(); b2.setName("old"); /* * 把b2引用指向null.讓b2引用所指的Book對象不在有引用指向它. * 垃圾回收器運行時,讓對象回收掉. */ b2 = null; /* * 強行運行垃圾回收器. */ System.gc(); } } class Book{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); System.out.println(getName()+"--->執行GC工作."); } } package test; /** * 測試垃圾回收器與finalize()方法 * @author Administrator */ public class GcTest { public static void main(String[] args) { Book b1 = new Book(); b1.setName("new"); Book b2 = new Book(); b2.setName("old"); /* * 把b2引用指向null.讓b2引用所指的Book對象不在有引用指向它. * 垃圾回收器運行時,讓對象回收掉. */ b2 = null; /* * 強行運行垃圾回收器. */ System.gc(); } } class Book{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected void finalize() throws Throwable { // TODO Auto-generated method stub super.finalize(); System.out.println(getName()+"--->執行GC工作."); } }
結果代碼
old--->執行GC工作.
上述就是小編為大家分享的如何解析關于Java垃圾回收的問題了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。