Java减少内存使用

Java减少内存使用,java,memory,jvm,Java,Memory,Jvm,我发现,如果我的应用程序有很多可用的空闲内存,那么它使用的内存就会超过它所需要的。我听说这种行为在所有Java应用程序中都很常见,但我不能接受 因此,问题是如何强制Java使用更少的内存 我知道我可以每隔几秒钟手动调用System.gc(),但是这样做可以吗?还有其他方法吗 p.S.我的应用程序在生产服务器上定期更新,我需要监控内存使用情况是否有泄漏等(通常没有泄漏,但如果出现泄漏,我应该尽快看到),并且我还需要预测升级硬件的时间。如果jvm不可预测地改变其内存需求,那么所有这些事情都很难做到。

我发现,如果我的应用程序有很多可用的空闲内存,那么它使用的内存就会超过它所需要的。我听说这种行为在所有Java应用程序中都很常见,但我不能接受

因此,问题是如何强制Java使用更少的内存

我知道我可以每隔几秒钟手动调用
System.gc()
,但是这样做可以吗?还有其他方法吗


p.S.我的应用程序在生产服务器上定期更新,我需要监控内存使用情况是否有泄漏等(通常没有泄漏,但如果出现泄漏,我应该尽快看到),并且我还需要预测升级硬件的时间。如果jvm不可预测地改变其内存需求,那么所有这些事情都很难做到。因此,我唯一想做的就是强制jvm在内存使用方面是可预测的(如果用户数量翻倍,那么内存也应该翻倍)

您可以通过调用java的
-Xmx
参数ie:

java -Xmx128M xxx
将以最大128Mb的速度运行(设置为“物理内存的1/4或1GB中的较小值”)

不要一直调用
System.gc()
,你要浪费的是你的时间;-)


还有,你为什么担心这个?当java接近其允许的最大内存时,它将无论如何首先执行GC扫描

如果调用System.GC(),您的可用内存将如何发挥作用?调用System.gc()甚至不是一个好的选择。如果您想要一个更具攻击性的垃圾收集器,则有相应的策略。
您应该做的是使用-Xmx以更少的内存启动它。不,这不好。gc()不保证垃圾收集器是否/何时启动。此外,System.gc()可能会调用垃圾收集器来收集垃圾,这通常会导致垃圾收集所花费的时间比运行应用程序所花费的时间更多

解决方案是确定应用程序所需的最大内存量(内存占用),并使用略多于内存占用的内存启动虚拟机。这里我假设您的应用程序没有内存泄漏

我发现,如果我的应用程序有很多可用的空闲内存,那么它使用的内存就会超过它所需要的。我听说这种行为在所有Java应用程序中都很常见,但我不能接受

这取决于你所说的“比它需要的更多的内存”。如果您的意思是,超过表示应用程序对象的最小内存,那么您是正确的

Java使用的内存超过了理论上可以忽略的最小值,这是一种标准行为。“更糟糕的是”,大多数JVM不会将内存返回给操作系统。。。即使该内存已被GC释放。这两个属性对于通用垃圾收集器的高效运行都是必需的

如果您不能接受这一点,则不应使用垃圾收集语言。使用C或C++。(但也要注意,C/C++内存分配器也不例外,即使是实现允许,也可以将内存还给内存。)
积极的一面是,如果给Java(事实上是任何GC’ed语言)足够的内存,它实际上会运行得更好。随着垃圾与非垃圾比率的增加,现代GC的工作效率更高,而更大的堆使得这种情况发生。(当然,您可能会走得太远,尤其是当应用程序与其他应用程序争夺真实内存时。)


正如其他答案所说,调用
System.gc()
没有帮助。这不太可能导致任何内存被返回。更糟糕的是,当垃圾级别太低而无法有效运行时,您很可能会运行GC,因此您将毫无益处地增加CPU时间


关于您的“PS”:

  • 我认为没有办法(可靠地)检测内存泄漏的存在。。。除了监控内存使用趋势外

  • 我不认为有一种方法(可靠地)预测你什么时候会购买新的硬件。。。除了监控内存使用(和其他)趋势之外

  • 我认为没有办法强迫你的应用程序的内存使用与用户数量成比例。。。除了设计/编码应用程序以使其按您想要的方式扩展之外


  • 另一方面,你可以对C/C++应用程序说同样的话。

    也许是时候重新思考为什么它不能被接受了。您能给出一个技术原因吗,或者是让您感到不舒服的原因吗?也许您不应该在生产服务器上进行测试?只有在您知道没有泄漏时才部署?这不是测试,当然我也有测试服务器,但它以不同的负载运行。听起来您需要对应用程序进行内存配置,以便了解内存的使用情况。查看您为应用程序提供的最大内存不是很有用。一个更好的数字是在GC之后使用了多少内存。考虑到内存成本非常低,我建议获得比您可能需要的内存更多的内存,并且您以后不必监视它或升级服务器(节省所有费用)32 GB:8 x 4 GB内存1600成本约为160美元。如果一开始就有这么多内存,您可能不需要对其进行监控,这样可以在系统的整个生命周期内轻松节省这么多内存。不,我不能将我的应用程序限制在内存中,因为当它在几周后停止工作时(这是一个服务器端应用程序,用户数量不断增加,因此我需要服务器所能提供的内存)那就别担心了。。。它会崩溃吗?如果是这样的话,那可能是内存泄漏,再多的
    System.gc()
    也无法修复这个问题。。。