2012-05-24 35 views
5

Tôi bắn lên console IRB JRuby tôi và gõ:JRuby - Cách khởi động bộ thu gom rác?

irb(main):037:0* GC.enable 
(irb):37 warning: GC.enable does nothing on JRuby 
=> true 
irb(main):038:0> GC.start 
=> nil 
irb(main):039:0> 

Làm thế nào tôi có thể tự kích hoạt hoặc khởi động rác JVM trong một chương trình?

Tôi hỏi vì tôi có một chương trình cần tạo khoảng 500 MB dữ liệu thử nghiệm và lưu nó trong MySQL. Chương trình sử dụng khoảng 5 cấp độ của vòng lặp lồng nhau, và nó treo với một ngoại lệ heap bộ nhớ JVM sau khi tạo ra khoảng 100 MBytes dữ liệu thử nghiệm vì không có bộ nhớ heap hơn. Tôi muốn cho phép bộ thu gom rác chạy sau mỗi lần chạy vòng lặp bên ngoài sao cho tất cả các đối tượng mồ côi được tạo ra trong các vòng bên trong có thể được làm sạch.

+1

Nó không có khả năng giúp đỡ, bởi vì nếu JVM hết bộ nhớ, nó sẽ chạy GC trước khi từ bỏ. Bạn có thể cần phải chắc chắn rằng bạn không giữ tài liệu tham khảo dài hơn chúng cần thiết và/hoặc tăng kích thước heap. – theglauber

Trả lời

10

Câu trả lời chính xác cho câu hỏi của bạn sẽ là:

require 'java' 

java_import 'java.lang.System' 

# ... 

System.gc() 

Mặc dù vậy, mang trong tâm trí mặc dù JVM thường không chạy GC, nó có thể hoặc không thể làm điều đó - rất phụ thuộc vào JVM thực hiện. Nó cũng có thể là một hit trên hiệu suất. Một câu trả lời tốt hơn rõ ràng là để đảm bảo rằng ở cuối vòng lặp lồng nhau, không có tham chiếu nào được giữ trên dữ liệu thử nghiệm mà bạn đang tạo ra, để chúng thực sự có thể được GC thu hồi sau này. Ví dụ:

class Foo; end 

sleep(5) 

ary = [] 
100_000.times { 100_000.times{ ary << Foo.new }; puts 'Done'; ary = [] } 

Nếu bạn chạy điều này với jruby -J-verbose:gc foo.rb, bạn sẽ thấy GC thường xuyên xác nhận quyền sở hữu đối tượng; điều này cũng khá rõ ràng khi sử dụng JVisualVM (ví dụ: sleep trong ví dụ này là để dành thời gian kết nối với quy trình Jruby trong JVisualVM).

Cuối cùng bạn có thể tăng bộ nhớ heap bằng cách thêm cờ sau: -J-Xmx256m; xem the JRuby wiki để biết thêm chi tiết.

Chỉnh sửa: Thật trùng hợp, đây là a mindmap on GC tuning gần đây được trình bày bởi Mario Camou tại Madrid DevOps được Nick Sieger đăng lại.

+0

Merci beaucoup Sébastien. Đề xuất của bạn rất hữu ích và giúp chúng tôi hỏi (và trả lời) nhiều câu hỏi hơn chúng tôi nghĩ. –

+1

Liên kết evernote dường như đã chết ... –

+0

Thans for the answer. một ví dụ khác: https://gist.github.com/Shobhit1/f4ec5c9f1f47f3b8e70bb7d27a78fba9 – shobhit1

-1

Không thể thực hiện được vì Gc sẽ được JVM tự động chạy. Hãy chắc chắn rằng bạn đang tạo ra các đối tượng chỉ khi nó được yêu cầu. Tránh tạo các đối tượng cấp lớp và cố gắng tìm hiểu xem đối tượng nào đang chiếm nhiều bộ nhớ hơn và chỉ tạo ra nó khi cần.

+0

Điều đó không đúng. Bạn có một số lời khuyên âm thanh, nhưng nó có thể chạy GC bằng tay. – Overbryd