为什么选择系统。 gc()似乎对某些JVM没有影响

时间:2010-07-08 16:02:33

标签: java memory memory-management jvm

我一直在开发一个小型Java实用程序,它使用两个框架:Encog和Jetty为网站提供神经网络功能。

代码已经“完成”,它完成了它需要做的所有事情,但是我在内存使用方面遇到了一些问题。在我的开发机器上运行时,当应用程序处理(训练神经网络)时,内存使用量似乎在大约4MB到13MB之间波动,并且最多使用大约18MB。这是非常好的用法,我认为这是因为我经常调用System.GC()。我这样做是因为处理时间对我来说无关紧要,但内存使用情况确实如此。

所以这一切都在我的机器上工作正常,但是一旦我把它放在我们的服务器上(共享unix主机具有内存限制),它使用大约19MB开始并且在做事时增加到数百MB的内存使用量。这些与我在测试中所做的一样。我认为,减少内存使用量的唯一方法是退出应用程序并重新启动它。

我能说的唯一区别是它正在运行的Java虚拟机。我不知道这个,我试图找到它以这种方式行事的原因,但是很多文档都假设你对Java和虚拟机有很好的了解。有人可以帮助我解释为什么会发生这种情况,也许有些事情要试图阻止它。

我已经看过使用GCJ来编译应用程序,但我不知道这是否应该花费大量时间以及它是否真的有用。

感谢您的帮助!

  • 更新:在Mac OS 10.6.3上开发,服务器在unix操作系统上,但我不知道是什么。 (服务器来自WebFaction)

5 个答案:

答案 0 :(得分:7)

  

我认为这是因为我   经常调用System.GC()

你不应该这样做,它几乎从来没用过。

垃圾收集器在有大量内存可以使用时效率最高,因此它往往会占用大部分内存。我认为您需要做的就是使用-Xmx32m命令行参数将最大堆大小设置为32MB - 默认值取决于JVM是否认为它在“服务器类”系统上运行,在这种情况下它假定您希望应用程序尽可能多地使用内存,以便提供更好的吞吐量。

顺便说一句,如果你在服务器上运行64位JVM,由于引用较多,它将合法地需要比32位JVM更多的内存(通常约30%)。

答案 1 :(得分:1)

您可能会考虑两点:

  • System.gc的调用可以通过命令行参数(-XX:-DisableExplicitGC)禁用,我认为该行为还取决于vm使用的gc算法。通常调用gc应该留给jvm
  • 只要有足够的内存可供jvm使用,我就没有看到使用这个内存来增加应用程序和gc性能的任何错误。正如Michael Borgwardt所说,你可以限制vm在命令行使用的内存量。

答案 2 :(得分:0)

此外,您可能希望了解在线部署JVM时启动的模式。我猜它是一个服务器VM。 在stackoverflow上查看两者之间的differences。另外,请查看实际部署中实际运行的垃圾收集器。看看你是否可以调整GC行为,或者更改GC算法。如果它是Sun JVM,请参阅-X选项。

答案 3 :(得分:0)

基本上,JVM会根据需要获取允许的内存量,以便尽可能快地进行“新”操作(这本身就是一门科学)。

因此,如果您使用了大量对象,然后将其丢弃,您将慢慢地确定地填满可用内存。然后你可以询问垃圾收集,但这只是一个提示,JVM可能会选择不听。

因此,您需要另一种机制来降低内存使用率。典型的方法是使用-Xoptions限制内存量,但要小心,因为您在PC上使用的JVM可能与您部署的JVM非常不同,因此内存需求可能不同。

是否故意要求内存使用率低?如果没有,那么让它运行并查看JVM的行为方式。使用jvisualvm进行附加和监控。

答案 4 :(得分:0)

也许服务器使用更多内存,因为您的应用程序负载较高,因此正在使用更多线程?如果有很多请求,Jetty将使用多个线程来分散负载。值得一看的是服务器上的线程数与测试机器上的线程数。