2010-07-08 94 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

相关问题