Chúng tôi đang tạo nhiều trình nạp lớp con để tải trong nhiều ứng dụng con vào một ứng dụng Java "vùng chứa", tạo mẫu triển khai nóng. Khi classpath của một trình nạp lớp cụ thể đã thay đổi (tức là các jars đã được thêm vào, xóa, cập nhật), trình nạp lớp cũ được bỏ đi (không được tham chiếu) và trình nạp lớp mới được tạo cho classpath mới của các lọ.Khi nào và như thế nào là một trình nạp lớp java được đánh dấu để thu thập rác?
Sau khi cập nhật đường dẫn lớp, kích hoạt triển khai nóng, chúng tôi đã lấy một vùng lưu trữ. Vùng kết xuất (sử dụng bộ phân tích bộ nhớ) chỉ ra rằng các trình nạp lớp cũ không bị thu gom rác. Một số lớp trong trình nạp lớp cha đã lưu vào bộ đệm ẩn các trình nạp lớp cũ. Những điều sau đây được gọi để xóa các bộ nhớ cache sau:
java.lang.ResourceBundle.clearCache(classLoader);
org.apache.commons.logging.LogFactory.release(classLoader);
java.beans.Introspector.flushCaches();
Ngay cả sau khi xóa bộ đệm trên, trình nạp lớp cũ vẫn không bị thu gom rác. Các tài liệu tham khảo còn lại để classloader bao gồm những điều sau đây:
- các lớp tải bởi classloader
- java.lang.Package của tạo ra bởi classloader tự
- java.lang.ProtectionDomain được tạo ra bởi classloader tự
Tất cả các bên trên là các tham chiếu vòng tròn trong trình nạp lớp, sẽ kích hoạt bộ sưu tập rác. Tôi không chắc tại sao nó không phải. Có ai biết lý do tại sao các trình nạp lớp cũ vẫn không được thu thập rác ngay cả với các tham chiếu vòng tròn?
Bạn sử dụng JVM nào (phiên bản chính xác)? Bạn có sử dụng bất kỳ tùy chọn JVM nào, điều đó có thể ảnh hưởng đến tải lớp không? Bạn có sử dụng bất kỳ thứ gì từ việc triển khai của Sun không? Ứng dụng có thao tác mã byte không? ... Môi trường có thể ảnh hưởng đến việc tải lớp học là gì? – cafebabe
Không liên quan đến câu hỏi chính của bạn, nhưng bạn đã xem xét một cái gì đó như OSGi thay vì làm khuôn khổ của riêng bạn hỗ trợ triển khai nóng? – SteveD
@bfoo Trong các thử nghiệm của chúng tôi, chúng tôi đang sử dụng Java 6. Không có tùy chọn JVM.Chúng tôi không sử dụng bất kỳ điều gì của Sun trong trường hợp đơn giản nhất. Không có thao tác mã byte. – onejigtwojig