2013-01-17 22 views
8

Chúng tôi có một quy trình JVM không thường xuyên chốt CPU ở mức 100%, với những gì dường như (theo visualgc) một đống rất gần cạn kiệt. Giả sử của chúng tôi là quá trình này là một cách mạnh mẽ GC'ing gây ra một CPU tăng đột biến, mà đang ảnh hưởng đến sức khỏe tổng thể của toàn bộ hệ thống (bao gồm các JVM khác làm những việc khác nhau).Làm thế nào để điều chỉnh một jvm để sụp đổ thay vì anh hùng GC cho đến khi sử dụng CPU 100%?

Quy trình này không quan trọng và có thể được khởi động lại. Có cách nào để điều chỉnh JVM thông qua dòng lệnh mà bắt đầu nó để làm cho nó rơi vào thanh kiếm riêng của mình hơn là nó giữ GC'ing và gây ra toàn bộ hộp phải chịu đựng?

Lưu ý là chúng tôi không nhận được một số nhận xét, vì vậy, heap không hoàn toàn cạn kiệt, nhưng hầu như không, chúng tôi nghĩ vậy.

Ngoài ra, một cái gì đó để cung cấp cho chúng tôi một số thông tin chi tiết về những gì trong JVM thực sự đang sử dụng CPU theo cách nó là để xác nhận/từ chối giả lập GC của chúng tôi?

+0

Nó sẽ là hữu ích để biết phiên bản Java, mà máy chủ ứng dụng bạn đang sử dụng. – gaborsch

+0

Tomcat 7, Sun/Oracle java 1.6. –

Trả lời

1

Bạn cần tìm cách thu thập một số thống kê về công việc GC. Trên thực tế có một số phương pháp để làm điều này. Tôi sẽ không làm copy-paste, chỉ cần cung cấp cho bạn liên kết đến câu hỏi tương tự:

Can you get basic GC stats in Java?

tôi tin rằng, bạn sẽ nghĩ như thế nào để phân tích số liệu thống kê này và quyết định khi nào GC là không ngừng hoạt động.

Vì câu hỏi này có chứa một số ý tưởng mới về việc áp dụng thống kê GC, tôi không nghĩ rằng đó là bản sao.

2

Điều tốt nhất cần làm là tìm ra rò rỉ bộ nhớ và sửa lỗi.

Một cách đơn giản để thoát vào cách sử dụng bộ nhớ cao:

if(Runtime.getRuntime().totalMemory()>100*1024*1024) 
    System.exit(0); 
+0

Cảm ơn - Tôi không chắc chắn rằng chúng tôi đang thực sự * rò rỉ * bộ nhớ (mặc dù chúng tôi có thể); quá trình này là quá trình chiếm một lượng lớn dữ liệu và tóm tắt, vì vậy có lẽ một thuật toán/thay đổi thiết kế là theo thứ tự. Điều đó nói rằng, bước 0 của chúng tôi là chỉ cần giết quy trình vi phạm để lưu hệ thống. Sau đó, chúng tôi chẩn đoán và khắc phục sự cố, nhưng giải pháp của bạn là điều chúng tôi sẽ xem xét và tôi hiểu bạn đến từ đâu. –

2

Cố gắng nhìn những gì các quy trình hiện đang chạy trong JVM.

  • với jstack bạn có thể làm một bãi chứa thread (có những cách khác để làm điều đó cũng)
  • với jvisualvm bạn có thể nhìn trộm vào tình trạng hiện tại của JVM (mất một số tài nguyên)
  • cũng lần lượt trên verbosegc (để chứng minh giả thuyết của mình rằng GC là thường xuyên)
3

Các nhà sưu tập song song và đồng thời có một "giới hạn chi phí" mà có thể làm những gì bạn muốn:

nếu có nhiều hơn 98% so với tổng thời gian là chi tiêu trong thu gom rác thải và ít hơn 2% của heap được phục hồi, một OutOfMemoryError sẽ được ném

Xem http://www.oracle.com/technetwork/java/javase/gc-tuning-6-140523.html để biết thêm thông tin.

+0

Tôi không nghĩ bạn có thể sửa đổi các thông số đó, phải không? – sharakan

+0

@sharakan - bạn không thể sửa đổi giới hạn thực tế, nhưng OP dường như mô tả các điều kiện mà tính năng này được tạo để xử lý. Nếu anh ta hiện không sử dụng bộ thu song song hoặc đồng thời, nó có thể đáng để chuyển sang một trong số chúng. – parsifal

+0

Hiện tại, chúng tôi đang điều tra tùy chọn này; cảm ơn. –

4

Chúng ta có thể có được số liệu thống kê từ

1): Tùy chọn -XX: + PrintGCTimeStamps sẽ thêm một tem thời gian vào lúc bắt đầu của mỗi bộ sưu tập. Điều này rất hữu ích để xem tần suất xuất hiện các tập hợp rác.

Với tùy chọn ở trên, chúng tôi có thể nhận được ước tính sơ bộ cho dù bạn giả định rằng quá trình này là GC'ing anh hùng gây ra một CPU tăng đột biến hay không.

Nếu giả sử của bạn là đúng thì bắt đầu điều chỉnh GC của bạn.

Both parallel collector and Concurrent Collector will throw an OutOfMemoryError if too much time is being 
spent in garbage collection: if more than 98% of the total time is spent in garbage collection and 
less than 2% of the heap is recovered, an OutOfMemoryError will be thrown. the option X:-UseGCOverheadLimit 
is enabled by default for both Parallel and concurrent collector . Check whether this option is disabled in 
your system . 

Để biết thêm thông tin về Gc chỉnh trong JVM tham khảo this và cho vm tùy chọn gỡ lỗi kiểm tra this