Java:不朽的对象和对象复活
什么是對象復活?
當沒有其他對象引用該對象時,該Java對象可以進行垃圾回收。 當JVM:s垃圾收集器最終將要刪除未使用的對象時,將調用該對象的finalize()方法。 但是,如果我們再次使用對象自己的finalize()方法重新創建對該對象的引用,則該對象可以復活。 在這種情況下,JVM將檢測到再次引用了該對象,并避免將其刪除。 隱喻地,該物體已經從死亡中復活了……
public class Immortal {private static final Set<Immortal> immortals = new HashSet<>();@Overrideprotected void finalize() throws Throwable {System.out.println(Immortal.class.getSimpleName() + "::finalize for " + this);immortals.add(this); // Resurrect the object by creating a new reference }}可以通過以下方式測試復活屬性:
public class NewMain {public static void main(String[] args) {new Immortal();System.gc();sleep(1_000);System.gc();prompt("Press any key...");}private static void prompt(String msg) {try {System.out.println(msg);System.in.read();} catch (IOException io) {}}private static void sleep(long duration) {try {Thread.sleep(duration);} catch (InterruptedException ie) {}}}這將給出以下輸出:
Immortal::finalize for com.blogspot.minborgsjavapot.resurected_object.Immortal@635cb856 Press any key...通過檢查Java堆,我們還可以看到盡管對象的終結器被調用,該對象仍然存在:
pemi$ jps 21735 NewMain 21736 Jpspemi$ jmap -histo 21735 | grep Immortal164: 1 16 com.blogspot.minborgsjavapot.resurected_object.Immortal終結器被調用了多少次?
如果以后取消引用了復活的對象,則該對象又有資格進行垃圾回收。 但是,這次
由于Java最多只能調用finalizer一次,因此不會再次調用finalize()方法。 我們可能還記得,不能保證終結器會被調用。 例如,如果程序由于任何原因終止,則僅放棄JVM中的對象,并且最終定形器將根本不會被調用,如在本示例中可以看到的:
當我們運行上述代碼片段時,我們觀察到從未調用Immortal::finalizer 。
對象復活好嗎?
與使用finalize()方法一樣,我們必須非常謹慎。 對我們Java開發人員的一般建議是根本不使用finalize() 。 此外,有人可能會說,復活一個對象與故意造成內存泄漏是一樣的。
但是,有一些有趣的對象復活應用程序。 也許我們想對我們的對象進行事后分析,而又不更改使用該對象的實際應用程序。 通過使用對象復活,我們可以保存那些對象并在以后分析它們的內部狀態,而與使用它們的應用程序無關。
翻譯自: https://www.javacodegeeks.com/2016/03/java-immortal-objects-object-resurrection.html
總結
以上是生活随笔為你收集整理的Java:不朽的对象和对象复活的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 确定活动的热点垃圾收集器
- 下一篇: linux分区查看命令(linux分区查