Làm thế nào để in các sự kiện thu gom rác lớp java?


9
 
java version "1.5.0_14" 
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_14-b03) 
Java HotSpot(TM) Server VM (build 1.5.0_14-b03, mixed mode) 

Tôi đang cố gắng gỡ lỗi một NullPointerException tôi nhận được để chuyển tham chiếu đến trường được xác định tĩnh. Để cụ thể hơn, tôi đang thiết lập toàn cầu trên một cá thể bộ nhớ làm việc Drools3.

workingMemory.setGlobal("log", workingMemorieslog); 

Giả định của tôi là Lớp nơi trường được định nghĩa tĩnh là thu gom rác. (Lớp nhận phải được sử dụng WeakReference hoặc một cái gì đó như thế, tôi không thực sự biết)

Bạn đề nghị gỡ lỗi này như thế nào? Tôi nghĩ rằng nếu tôi có thể biết chính xác khi nào GC của JVM dỡ một lớp/cá thể của một lớp thì tôi có thể thu hẹp nguyên nhân của hành vi lỗi. (Nếu không phải là thời gian chính xác của sự kiện ít nhất là nhận được một dấu hiệu cho thấy một cái gì đó đã xảy ra).

Cảm ơn bạn, Maxim.

  0

Câu hỏi hay, theo dõi tốt, câu trả lời hay của riêng bạn. +1 cho cả câu hỏi và câu trả lời. 22 feb. 092009-02-22 20:00:14

10

Để theo dõi hoạt động GC thêm video này vào lệnh java:

verbose: gc -XX: + PrintGCTimeStamps -XX: + PrintGCDetails

NPE rằng bạn đang nhận được có lẽ bạn chuyển giá trị null.

  0

Cảm ơn bạn đã trả lời, Tôi đã chạy với -XX: + PrintGCDetails -verbose: gc -Xnoclassgc và tôi vẫn không thấy thông tin tải/dỡ lớp. Sản lượng duy nhất tôi se là các dòng như: [GC [PSYoungGen: 4096K-> 630K (4736K)] 4096K-> 790K (48064K), 0,0032750 giây] 22 feb. 092009-02-22 00:27:12

  0

Vì câu trả lời này phù hợp nhất với chủ đề ban đầu của câu hỏi Tôi chấp nhận nó như là câu trả lời. Cảm ơn bạn. 22 feb. 092009-02-22 16:31:10


0

Bạn có theo dõi ngăn xếp không?

Bạn đã thử bước vào phương pháp 'setGlobal' (giả sử bạn có mã) để xem điều gì đang xảy ra?


2

Tại sao không giữ cho lớp trong bộ nhớ, sau đó xem nếu nó vẫn xảy ra, nếu nó xảy ra thì vấn đề của bạn nằm ở nơi khác. Nếu không thì bạn biết vấn đề nằm trong bộ sưu tập rác.


1

Nó chỉ ra rằng nhật thực là vấn đề chính ở đây.

Tôi sẽ giải thích:

Tôi đã bọc webapp của chúng tôi bằng phương thức main() để kiểm tra hiệu suất. Chúng tôi sử dụng rất nhiều mã bên thứ 3, cụ thể là Apache commons-pool.

Hóa ra chúng tôi đã có một số phiên bản của lọ lan truyền qua các dự án (các dự án nhật thực). Ứng dụng của tôi sử dụng các dự án này có commons-pool-1.3, một dự án khác có commons-pool-1.2.

Khi được tải bằng cách sử dụng thùng chứa servlet (Tomcat6) trình tải lớp webapp có mức độ ưu tiên đầu tiên nên nó luôn tải phiên bản webapp. Khi tôi bắt đầu ứng dụng bằng cách sử dụng main() eclipse trong hành vi của nó không phải là rất khôn ngoan xuất khẩu các dự án phụ thuộc lọ trong -classpath TRƯỚC KHI những người trong dự án hiện tại.

Xung đột giữa 2 phiên bản của commons-pool, gây ra một hành vi không được xác định - Trên một đối tượng mượn là SOMETIMES quyết định tạo một đối tượng mới. Tôi đã không nhìn bên trong mã thực hiện, tôi giả định rằng đây là một cái gì đó để làm với một bản đồ tĩnh giữ bởi GenericKeyedObjectPool (lớp có vấn đề). Bởi vì một cá thể mới được tạo ra, nó thực sự chứa một tham chiếu null đến toàn cầu được đề cập.

Giải pháp cho may mắn của tôi khá đơn giản, nhóm dùng chung của tôi chỉ được sử dụng bởi webapp của tôi để tôi có thể xóa nó khỏi tất cả các dự án được tham chiếu, nếu không tôi sẽ cố gắng nâng cấp tất cả lên một phiên bản duy nhất.Nếu tôi không thể làm được, tôi thực sự không biết tôi sẽ làm gì. Đây là một mặc định rất kỳ lạ của nhật thực.

Cảm ơn bạn đã đọc và trợ giúp.

// ps. 3 ngày. Đó là thời gian tôi đã dành cho việc hiểu những gì tôi đã làm sai trong mã thay thế servlet của tôi. Hóa ra tôi thậm chí không phải là vấn đề. : P

+1

FYI: Nếu bạn có vấn đề tham chiếu đối tượng lạ, hãy thử đăng nhập 'ProblemClass.class.getProtectionDomain(). GetCodeSource(). GetLocation(). ToExternalForm()' Điều này sẽ trả về tệp jar hoặc lớp mà lớp đã được tải . Đó là một thủ thuật vô giá khi gỡ lỗi các ứng dụng web, thường gặp phải các vấn đề về trình nạp lớp không xác định. 02 jan. 132013-01-02 06:20:21