2010-07-08 78 views
3

我一直在開發一個使用兩個框架的小型Java實用程序:Encog和Jetty爲網站提供神經網絡功能。爲什麼系統。 gc()似乎對某些JVM沒有影響

代碼「完成」了,它完成了它需要做的所有事情,但是我在內存使用方面遇到了一些問題。在我的開發機器上運行時,當應用程序正在執行操作(訓練神經網絡)時,內存使用量似乎在大約4MB和13MB之間波動,最多使用大約18MB。這是非常好的用法,我認爲這是由於我相當經常地調用System.GC()。我這樣做是因爲處理時間對我來說並不重要,但是內存使用情況確實如此。

因此,它在我的機器上工作正常,但只要我把它放到我們的服務器上(共享內存限制的unix主機),它使用大約19MB開始,並在上網時升至數百MB的內存使用量的東西。這些和我在測試中一樣。我相信,減少內存使用量的唯一方法是退出應用程序並重新啓動它。

我可以說的唯一區別就是它正在運行的Java虛擬機。我不知道這一點,我試圖找出這種方式的原因,但很多文檔假設了Java和虛擬機的豐富知識。是否有人可以幫忙解釋爲什麼會發生這種情況,或許有些事情可以阻止它。

我已經看過使用GCJ編譯應用程序,但我不知道這是我應該投入大量時間,是否會真正幫助。

感謝您的幫助!

  • 更新:在Mac OS 10.6.3上開發和服務器上的Unix操作系統,但我不知道是什麼。 (服務器是WebFaction)
+0

是您的開發環境Windows還是Linux? – 2010-07-08 16:06:44

+0

在Mac OS 10.6上進行開發。對不起,我的意思是說這樣。 – danpalmer 2010-07-08 16:12:20

回答

7

我認爲這是由於這樣的事實,我 調用System.gc()相當定期

你不應該這樣做,這是幾乎從來沒有用。

當垃圾收集器有大量的內存可供使用時,垃圾收集器的工作效率最高,因此它往往會佔用大部分內存。我認爲你需要做的就是將最大堆大小設置爲32MB,命令行參數爲-Xmx32m - 默認取決於JVM是否相信它在「服務器類」系統上運行,在這種情況下,它假設你希望應用程序儘可能多地使用內存以提供更好的吞吐量。

順便說一句,如果你在服務器上的64位JVM上運行,由於引用較大,它將合法地需要更多的內存(通常約30%),而不是32位的JVM。

+0

理想情況下,內存使用量不能超過40MB。這是關於我在服務器上爲這個應用程序玩的。我假設服務器是64位的,但是有可能/建議強制它使用32位虛擬機? 當我說測試中的RAM使用量在4到13MB之間波動時,我相信每次我調用System.GC()時,使用量會從13下降到4左右,但我不確定。 – danpalmer 2010-07-08 16:14:38

+0

所以把-Xmx40m -Xms40m和你的程序將總是使用正好40M的內存。然後刪除所有對System.gc的調用,因爲這是糟糕的Java風格。 JVM會爲你處理GC,只是給它一定的內存邊界(就像我上面提到的那樣) – bwawok 2010-07-08 16:22:13

+0

好的,謝謝,我會試試這個。我不認爲System.GC()是一個好主意。在完成了一些C#之後,我絕對不會這麼做,當我在Java中完成時,它看起來像是一個'黑客',但它似乎有所幫助。我會隨着這些想法去做報告。 – danpalmer 2010-07-08 16:26:23

1

兩點可以考慮:的System.gc

  • 呼叫可以通過一個命令行參數(-XX:-DisableExplicitGC)被禁用,我覺得行爲還取決於虛擬機使用的GC算法。通常調用gc應該留給jvm
  • 只要有足夠的內存可用於jvm,我就不會在使用此內存來增加應用程序和gc性能時看到任何錯誤。正如Michael Borgwardt所說,你可以限制虛擬機在命令行中使用的內存量。
+0

如果我限制可用內存量,如果應用程序通常要使用更多內存,會發生什麼情況?它會崩潰還是減慢很多或什麼? – danpalmer 2010-07-08 16:19:43

+0

一旦你通過你的XMX它會崩潰。你不應該在你的代碼中調用System.gc,這不是Java的方式。 – bwawok 2010-07-08 16:21:20

+0

如果你的程序分配內存並且沒有剩餘空間,它將首先觸發gc。所以你可能會看到更多的gc活動和更低的性能。只有當gc沒有釋放足夠的內存時,你纔會得到一個OutOfMemoryError。這或多或少像是崩潰,因爲幾乎不可能從中恢復。 – 2010-07-08 16:33:28

0

另外,您可能想要了解在聯機部署JVM時啓動的模式。我猜它是一臺服務器虛擬機。 看看這兩個之間的differences在這裏在stackoverflow。另請參閱實際部署中實際運行的垃圾收集器。查看是否可以調整GC行爲或更改GC算法。如果是Sun Java虛擬機,請參閱-X選項。

0

基本上,JVM根據需要獲取允許的內存量,以便儘可能快地進行「新」操作(這本身就是一門科學)。

所以,如果你有很多的對象被使用,然後丟棄,你會慢慢地,肯定填滿可用內存。那麼你可以垃圾收集,但它只是一個提示,並且JVM可能選擇不聽。

因此,您需要另一種機制來保持內存使用量不變。典型的方法是使用-X選項限制內存量,但要小心,因爲您在PC上使用的JVM可能與您部署的JVM非常不同,因此內存需求可能會有所不同。

是否存在低內存使用率的故意要求?如果沒有,那就讓它運行,看看JVM的行爲。使用jvisualvm進行附加和監視。

0

也許服務器使用更多的內存,因爲你的應用程序有更高的負載,所以更多的線程正在使用?如果有很多請求,Jetty將使用多個線程來分散負載。它值得關注服務器上的線程數量與您的測試機器上的線程數量。

+0

在那裏,我們目前只有少數用戶,並且看到了使用情況,所以我們在開發和生活中都有相同的用法進行測試。另外,我給Jetty使用了線程池,我確切知道它有多少個線程。 – danpalmer 2010-08-04 09:28:02

相關問題