2011-10-24 35 views
11

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ệu finalize() có được gọi hay không.
+0

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. –

Trả lời

10

Không, Java không đảm bảo rằng khi thoát chương trình, GC sẽ kích hoạt. Nếu bạn muốn một hoạt động để làm đúng theo lối ra sử dụng phương pháp Runtime.addShutdownHook. Đọc this Bài viết về những gì SPEC nói.

Đặc điểm kỹ thuật cho nền tảng Java đưa ra rất ít lời hứa về cách thu thập rác thực sự hoạt động. Dưới đây là những gì Java Virtual Đặc điểm kỹ thuật máy (JVMS) đã nói về quản lý bộ nhớ.

Heap được tạo trên máy ảo khởi động. Lưu trữ vùng lưu trữ cho các đối tượng được khôi phục bởi hệ thống quản lý bộ nhớ tự động (được gọi là làm bộ thu gom rác); các đối tượng không bao giờ được phân bổ rõ ràng. Máy ảo Java không có loại hệ thống quản lý lưu trữ tự động và kỹ thuật quản lý lưu trữ có thể được chọn theo yêu cầu hệ thống của người triển khai.1. được xác định là thực sự quan trọng và hữu ích - một mô hình thu gom được xác định rõ ràng có thể không thể triển khai trên tất cả các nền tảng. Tương tự, nó có thể loại bỏ tối ưu hóa hữu ích và làm tổn thương hiệu suất của của nền tảng trong thời gian dài.

Mặc dù không có một nơi có chứa một định nghĩa đầy đủ của cần hành vi thu gom rác, phần lớn các model GC được ngầm định thông qua một số phần trong kỹ thuật Java Ngôn ngữ và JVM.Mặc dù không có sự bảo đảm nào về quy trình chính xác của , tất cả các máy ảo tuân thủ chia sẻ vòng đời đối tượng cơ bản được mô tả trong chương này.

+0

Liệu nó (ví dụ: spec) nói như vậy bất cứ nơi nào? – Kashyap

+1

Mặc dù mô tả bạn cung cấp vẫn không thực sự nói rằng GC không được thực hiện khi thoát, tôi nghĩ rằng nó đủ rõ ràng rằng nó còn lại để JVMs impls .. Cảm ơn thông tin abt 'addShutdownHooks()', không biết điều đó. – Kashyap

+1

Không có tuyên bố tiêu cực trong đặc điểm kỹ thuật đọc 'GC không nhất thiết phải chạy khi thoát'. Sự mơ hồ có chủ ý trong spec và các tuyên bố rộng tôi trích dẫn là tất cả những gì được nêu. –

3

Xem Runtime.runFinalizersOnExit(). Lưu ý rằng nó không được chấp nhận và lưu ý phần còn lại của bài bình luận. Tôi nghĩ rằng bạn có thể suy luận hợp pháp từ tất cả những gì mà nó được tắt theo mặc định, nhưng bạn cũng nên lưu ý rằng nó có thể được bật.

Các vấn đề liên quan