2012-05-24 56 views
5

我啓動了我的JRuby IRB控制檯和類型:JRuby - 如何啓動垃圾回收器?

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> 

我如何可以手動啓用或程序中啓動JVM的垃圾?

我問,因爲我有一個程序需要生成約500 MBytes的測試數據並將其保存在MySQL中。該程序使用大約5級嵌套循環,並且在生成大約100 MBytes的測試數據後,由於沒有更多堆內存,它會因JVM內存堆異常而崩潰。我想讓外部循環的每次運行之後讓垃圾收集器運行,以便可以清理內部循環中創建的所有孤立對象。

+1

這不太可能有幫助,因爲如果JVM耗盡內存,它會在放棄之前運行GC。你可能需要確保你沒有持有引用超過他們需要和/或增加堆大小。 – theglauber

回答

10

確切的回答你的問題是:

require 'java' 

java_import 'java.lang.System' 

# ... 

System.gc() 

不過,銘記儘管JVM通常運行GC,它可能會或可能不會做到這一點 - 非常依賴於JVM實現。它在性能上也可能相當受歡迎。

更好的答案顯然是確保在嵌套循環結束時,不會在您生成的測試數據上進行引用,以便以後可以通過GC回收它們。例如:

class Foo; end 

sleep(5) 

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

如果你運行這個與jruby -J-verbose:gc foo.rb,你應該看到GC經常聲稱的對象;使用JVisualVM也很明顯(示例中的sleep是爲了給JVisualVM中的Jruby進程提供一些時間連接)。

最後,您可以通過添加以下標誌來增加堆內存:-J-Xmx256m;有關更多詳情,請參閱the JRuby wiki

編輯:巧合的是,這裏是a mindmap on GC tuning最近由Mario Camou在馬德里DevOps上發佈,由Nick Sieger重新發布。

+0

Merci beaucoupSébastien。你的建議非常有用,幫助我們提出(並回答)比我們想象的更多的問題。 –

+1

該evernote鏈接似乎已經死了... –

+0

Thans爲答案。 再舉一個例子:https://gist.github.com/Shobhit1/f4ec5c9f1f47f3b8e70bb7d27a78fba9 – shobhit1

-1

這是不可能的,因爲Gc將由JVM自動運行。確保只在需要時創建對象。避免創建類級別的對象,並嘗試找出哪些對象獲取更多內存,並僅在需要時才創建它。

+0

這是不正確的。您有一些合理的建議,但可以手動運行GC。 – Overbryd