我发现如果我的应用程序有大量可用内存,它会占用更多内存。我听说这种行为对于所有Java应用程序都很常见,但对我来说这是不可接受的。
所以问题是如何强制Java使用更少的内存?
我知道我可以每隔几秒钟手动调用System.gc()
,但这样做是否正常,还有其他方法吗?
PS 我的应用程序在生产服务器上定期更新,我需要监控一些泄漏的内存使用情况等等(通常没有泄漏,但如果有一个泄漏,我应该尽快看到它),我还需要预测升级硬件的时间。如果jvm无法预测地改变其记忆饥饿,所有这些事情都很难做到。所以我唯一想要的就是强制jvm在内存使用方面是可预测的(如果用户数量增加一倍,内存也会增加一倍)
答案 0 :(得分:7)
您可以通过使用-Xmx
参数调用java来告诉它使用更少的内存,即:
java -Xmx128M xxx
将以最大128Mb(by default in Java 6运行,设置为“物理内存的1/4或1GB”
不要一直打电话给System.gc()
......这是你浪费的时间; - )
另外,你为什么担心这个?当java接近允许的最大内存时,无论如何都会进行GC扫描
答案 1 :(得分:4)
我发现如果我的应用程序有大量可用内存,它会占用更多内存。我听说这种行为对于所有Java应用程序都很常见,但对我来说这是不可接受的。
这取决于你的意思“更多的内存而不是它需要”。如果您的意思是,超过表示应用程序对象的最小内存,那么您是正确的。
标准行为是Java使用的内存比理论上可以使用的最小内存少。 “更糟糕的是”,大多数JVM都没有将内存返回给操作系统......即使该内存已被GC释放。对于通用垃圾收集器的有效操作,这两个属性都是必需的。
如果这对您不可接受,则不应使用垃圾收集语言。使用C或C ++。 (但也要注意,C / C ++内存分配器能够将内存返回给操作系统是不寻常的......即使实现允许它。)
这方面的积极方面是,如果你给它足够的内存,Java(实际上任何GC语言)实际上会运行得更好。随着垃圾与非垃圾的比例增加,现代GC的工作效率更高,而更大的堆使这种情况发生。 (当然,你可以走得太远,特别是如果应用程序与其他东西竞争真正的内存。)
正如其他答案所说,致电System.gc()
并没有帮助。它不太可能导致任何内存被回馈。更糟糕的是,当垃圾级别太低而无法进行有效操作时,您很可能会运行GC,因此您将增加CPU时间而无益。
关于你的“PS”:
除了监控内存使用趋势之外,我认为没有办法(可靠地)检测内存泄漏的存在。
我认为除了监视内存使用(和其他)趋势之外,还有一种方法(可靠地)预测新硬件的时间。
我认为有一种方法可以强制您将应用程序的内存使用量与用户数量成比例...除了设计/编写应用程序以使其按照您希望的方式进行扩展。 / p>
另一方面,您可以对C / C ++应用程序说同样的事情。
答案 2 :(得分:3)
首先,如果你打电话给System.gc(),你的免费记忆会有什么帮助?并且调用System.gc()甚至不是一个好的选择。如果你想要一个更积极的垃圾收集器,那么就有了相应的策略。 你应该做的是用-Xmx
以较少的内存启动它答案 3 :(得分:2)
不,不行。如果/何时垃圾收集器将启动,System.gc()不保证。更多的是,System.gc()可能会调用垃圾收集器,导致比运行应用程序花费更多的时间来收集垃圾。
解决方案是确定应用程序所需的最大内存量(占用空间),并以比占用空间略多的内存启动虚拟机。我假设您的应用程序没有内存泄漏。