2012-06-12 13 views
10

Tôi có chu kỳ dài của GC. từ các kiểm tra tôi thấy có quá nhiều đối tượng trong khu vực cũ (cũ) của Heap. Có bất kỳ sự không phù hợp nào để biết đối tượng nào nằm trong vùng nào của vùng heap hay bất kỳ tĩnh nào về các đối tượng này.
Tôi đang sử dụng Sun/Oracle HotSpot JVM (Java 6).có cách nào để biết đối tượng nào trong khu vực "cũ" của Heap

CHỈNH SỬA: chi tiết hơn một chút về vấn đề của tôi:
Tôi có một Heap lớn (32 GB) và có vẻ như ngay cả khi vùng cũ Heap chỉ đủ 30%, chạy GC theo cách thủ công để tạm dừng 15 giây. Tôi muốn biết những đối tượng nào là "những người sống sót" vẫn còn trong khu vực cũ, để biết được việc tạo ra đối tượng nào để tối ưu hóa.

+1

Tôi chỉ sử dụng [Visualvm] (http://docs.oracle.com/javase/6/docs/technotes/guides/visualvm/intro.html), [Visualgc] (http: //java.sun. com/performance/jvmstat/visualgc.html) và [Jconsole] (http://docs.oracle.com/javase/1.5.0/docs/guide/management/jconsole.html#gc). Tôi không nhớ bất kỳ trong số này có thể liệt kê các đối tượng được thuê. Họ sẽ cung cấp cho bạn tuy nhiên một số số liệu thống kê trên khu vực được thuê. Vì vậy, tôi chỉ đề nghị bài viết này http://java.sun.com/docs/hotspot/gc/index.html và +1 – bpgergo

+0

Tập hợp đầy đủ các thông số khởi động JVM của bạn là gì? – moodywoody

Trả lời

7

Tôi không biết về bất kỳ công cụ/tiện ích nào hoạt động với các JVM thế hệ hiện tại.

Nhưng mặt trái là tôi không thấy tiện ích này hữu ích như thế nào.

Thời gian GC dài thường xảy ra do heap của bạn quá đầy. Khi heap đạt đến 100% đầy đủ, lượng thời gian dành cho GC có xu hướng tăng theo cấp số nhân. Trong trường hợp xấu nhất, heap đầy hoàn toàn và ứng dụng của bạn nhận được OutOfMemoryError. Có hai giải pháp khả thi:

  • Nếu nguyên nhân gốc rễ là đống là quá nhỏ (đối với kích thước của vấn đề mà ứng dụng của bạn đang cố gắng để giải quyết) sau đó, hoặc tăng kích thước heap, hoặc tìm kiếm một cách để giảm bộ làm việc của ứng dụng; tức là số lượng/kích thước của các đối tượng cần phải có "hoạt động" trong khi tính toán.

  • Nếu nguyên nhân gốc là rò rỉ bộ nhớ, hãy tìm và sửa chữa nó.

Trong cả hai trường hợp, sử dụng một hồ sơ bộ nhớ sẽ giúp bạn phân tích vấn đề. Nhưng bạn không cần phải biết những vật thể nào trong thế hệ cũ. Nó không liên quan đến nguyên nhân gốc rễ của vấn đề hoặc giải pháp cho vấn đề.


Tôi muốn biết đối tượng là "người sống sót" những gì còn lại trong khu vực cũ, để biết rằng những đối tượng sáng tạo để tối ưu hóa.

Điều này bắt đầu có ý nghĩa hơn một chút. Có vẻ như bạn cần phải tìm ra những đối tượng nào tồn tại lâu dài ... chứ không phải đặc biệt là không gian nào chúng sinh sống. Bạn có thể làm điều đó bằng cách sử dụng jhat để so sánh chuỗi các ảnh chụp nhanh heap. (Có thể có cách tốt hơn ...)

Tuy nhiên, tôi vẫn không nghĩ rằng cách tiếp cận này sẽ hữu ích. Vấn đề là một GC đầy đủ cần phải đi qua tất cả các đối tượng có thể truy cập (cứng, mềm, yếu, phantom). Và nếu bạn đã có một đống 32Gb đó là 30% đầy đủ bạn vẫn còn có rất nhiều đối tượng để đánh dấu/quét/di dời. Tôi nghĩ rằng giải pháp có khả năng là sử dụng một bộ thu đồng thời và điều chỉnh nó để nó có thể theo kịp với tỷ lệ phân bổ đối tượng của ứng dụng của bạn.

Có vẻ như bạn có thể đang gọi số System.gc() trực tiếp từ mã của bạn. Đừng làm thế! Gọi System.gc() sẽ (thường) khiến JVM thực hiện toàn bộ bộ sưu tập rác. Đó là khá nhiều đảm bảo để tạm dừng.Tốt hơn hết là rời JVM để quyết định thời điểm chạy bộ thu.

Cuối cùng, không rõ ý bạn là gì bằng cách "tối ưu hóa tạo đối tượng". Bạn có nghĩa là giảm tỷ lệ tạo đối tượng? Hay bạn đang nghĩ đến điều gì đó khác để quản lý việc lưu giữ các đối tượng tồn tại lâu dài (được lưu trong bộ nhớ cache)?

0

Tôi chưa bao giờ thấy một công cụ cho phép "khám phá" các đối tượng trong một thế hệ đã cho.

Tôi đã quen với Netbeans Profiler. Nó không thể thực sự làm những gì bạn đang yêu cầu nhưng nó có một công cụ có thể cung cấp cho bạn những ý tưởng về những gì đang xảy ra.

Chạy ứng dụng bằng Profiler, chọn Memory, sau đó trong Live Results bạn có một cột Generations. Nó không cho bạn biết thế hệ của mỗi đối tượng nhưng nó cung cấp cho bạn số lượng Surviving Generations. Vì vậy, nếu số lượng lớn hơn 1 thì có thể là trong số người được thuê (có thể trong không gian sống sót), nếu con số luôn phát triển bạn bị rò rỉ bộ nhớ.

0

Tôi không nghĩ có bất kỳ Tiện ích nào có thể cho bạn biết về không có đối tượng trong các thế hệ khác nhau.

  1. Một cách là Bạn có thể sử dụng jconsole kèm theo jdk. với sự giúp đỡ của jconsole bạn có thể kết nối với ứng dụng của bạn và theo dõi tất cả các thế hệ, ở đây bạn có thể nhận được một số con số tôi không chắc chắn.
  2. Cách khác là bạn có thể lấy một bãi chứa bằng cách sử dụng jmap và sau đó phân tích nó bằng cách sử dụng công cụ eclipse MAT.
  3. Hoặc bạn có thể chạy ứng dụng của bạn với bên dưới JVM tranh cãi và trong đăng nhập của bạn có thông tin về GC của

GC logging is enabled using JVM arguments; below are the arguments I use. (Note: the log file specified as file is reset each time the VM starts.

-verbose:gc -Xloggc:file

Tôi nghĩ rằng có thể hữu ích cho bạn.

1

Đường ray voi công cụ có thể lập cấu hình tạo đối tượng và cái chết, elephantTrack. Với điều này, bạn có thể tìm ra loại đối tượng nào tồn tại lâu hơn mong đợi và với lịch sử phương pháp, có thể có được các đối tượng chính xác.

Nhưng đống lớn có nghĩa là thời gian hồ sơ rất dài và tệp hồ sơ rất lớn.

+0

Nhưng ... theo trang web, nó không hoạt động cho Java 1.7 và (có lẽ là) các phiên bản sau này. –