PS: Tôi biết cách dọn dẹp chính xác, không phụ thuộc vào finalize()
.JVM/GC có gọi `finalize()` trên chương trình/thoát khỏi chuỗi không?
Java không đảm bảo rằng khi thoát chương trình, việc thu gom rác thích hợp sẽ được thực hiện?
Ví dụ: cho phép nói rằng tôi đã giữ một số dữ liệu trong bộ nhớ cache thay vì serializing nó thường xuyên, tôi cũng thực hiện finalize()
với hy vọng rằng nếu vì lý do gì (ngoại trừ tai nạn) chương trình của tôi thoát duyên dáng, sau đó bộ nhớ cache sẽ được ghi vào DB/file/một số -storage bởi mã của tôi trong phương thức finalize(). Nhưng theo thử nghiệm nhỏ sau đây có vẻ như JVM không dọn dẹp bộ nhớ "duyên dáng", nó chỉ thoát.
Java spec (xem thoát chương trình) nói NOTHING abt cách bộ nhớ/gc được xử lý khi thoát. Hay tôi nên nhìn vào một phần khác của spec?
Hãy theo gương (đầu ra ở cuối) sử dụng 1.6.0.27 64 bit, trên Windows 7
public class Main {
// just so GC might feel there is something to free..
private int[] intarr = new int[10000];
public static void main(String[] args) {
System.out.println("entry");
Main m = new Main();
m.foo();
m = new Main();
// System.gc();
m.foo();
m = null;
// System.gc();
System.out.println("before System.exit(0);");
System.exit(0);
}
@Override
protected void finalize() throws Throwable {
System.out.println("finalize()");
super.finalize();
}
public void foo() { System.out.println("foo()"); }
}
/*
* Prints:
* entry
* foo()
* foo()
* before System.exit(0);
*/
Variations:
- Nếu tôi bỏ ghi chú bất kỳ một
System.gc()
sau đó không được gọi làfinalize()
. - Nếu tôi bỏ ghi chú cả
System.gc()
thìfinalize()
được gọi hai lần. - Cho dù
System.exit()
được gọi hay không không ảnh hưởng đến việc liệufinalize()
có được gọi hay không.
Vấn đề bạn có là một chương trình có thể chết một cách không đúng lúc bất cứ lúc nào. Bạn cũng có thể cần phải có khả năng dọn dẹp khi khởi động lại. –