Java 如何指示JVM保持尽可能低的内存占用?

Java 如何指示JVM保持尽可能低的内存占用?,java,jvm,Java,Jvm,我有一个java程序,可以执行5种不同的任务。当我使用-Xmx512m内存参数运行程序时,任务1-4运行正常,但任务5内存不足。当我使用-Xmx1024m运行该程序时,所有5个任务都可以正常运行,但之前使用512m堆运行正常的任务1-4现在几乎占用了1024m堆的所有资源。如果使用-Xms128m-Xmx1024m,也会发生同样的情况 什么是内存参数来指示JVM保持内存利用率低(例如,任务1-4为512m),并且仅在实际需要时使用更多内存(例如,任务5) 也许我需要一种比默认设置更频繁地激活垃圾

我有一个java程序,可以执行5种不同的任务。当我使用-Xmx512m内存参数运行程序时,任务1-4运行正常,但任务5内存不足。当我使用-Xmx1024m运行该程序时,所有5个任务都可以正常运行,但之前使用512m堆运行正常的任务1-4现在几乎占用了1024m堆的所有资源。如果使用-Xms128m-Xmx1024m,也会发生同样的情况

什么是内存参数来指示JVM保持内存利用率低(例如,任务1-4为512m),并且仅在实际需要时使用更多内存(例如,任务5)


也许我需要一种比默认设置更频繁地激活垃圾收集器的方法?

我认为您对JVM的工作方式有误解。这不是GC问题或“任务”问题

您的任务存在内存泄漏,或者它们被设计为保留越来越多的内存

-Xmx1024m设置JVM可以分配的最大内存。这就像你只有1024兆的物理内存,没有虚拟内存一样

用任务的定义更新你的问题会很有帮助。这5个JVM是独立的吗?或者在一个JVM中只有5个工作单元

更新

我不希望程序总是使用所有1g堆。我的意图是指示JVM在可以管理的情况下使用512m堆,并且仅在需要时使用更多内存。当不再需要内存时,返回到512m甚至更少的内存量

设置-Xmx1024m并不意味着JVM将使用所有内存。这只是一个最大限度。设置Xms直到设置要使用的最小内存量。您的程序最终决定正在使用的内存的运行量。如果它达到了-Xmx设置的限制,那么它将抛出OutOfMemoryError

您可以通过调用
System.gc()
来建议JVM运行垃圾收集器。请注意,我建议您不能强制GC运行。您可能运行在一个甚至拒绝执行GC的平台上。您还需要了解它为您的应用程序选择了什么样的GC算法。我会看看这里


如果您需要对内存使用进行如此精细的控制,那么您需要选择JVM之外的其他东西。

通过将-Xmx1024m传递给第个VM,您基本上告诉VM它可以使用多达1G的堆,最终它会这样做。VM在需要时开始运行垃圾收集,例如当堆用完时,这取决于可用的堆大小。
如果您知道要在外部运行哪个任务(我猜您是这样做的,因为您将它作为cmd行参数传递),为什么不也从外部设置-Xmx呢?

尝试使用以查看内存消耗。然后,您可以使用jhat可视化堆内容并识别泄漏。

这两个参数建议jvm在需要调整堆大小时:

-XX:MaxHeapFreeRatio=10
-XX:MinHeapFreeRatio=10
这几乎意味着,如果在gc之后,超过10%的堆是空闲的,它将尝试将内存返回给操作系统。并且,只有在gc之后使用了超过90%的堆时,它才会增加堆


这可能会降低程序的速度,因为gc将不断更改分配的内存大小。如果您的程序在短时间内分配了大量内存,则可能根本没有效果

你如何区分哪些任务使用了多少内存?为什么任务1-4使用多少内存很重要?您已经为整个程序分配了千兆字节。@Poindexter我传递了一个命令行参数来指示要运行的任务。然后我使用
prstat
查看程序的内存利用率。@Michael Myers我不希望程序总是使用所有1g堆。我的意图是指示JVM在能够管理的情况下使用512m堆,并且仅在需要时使用更多内存。当不再需要额外的内存时,请返回512m甚至更少。JVM在启动时保留最大堆大小,并且永远不会将其返回给操作系统(除非退出)。除非您的计算机非常有限,否则我不会担心,512MB的内存大约值3美元。当我运行程序时,我会传递一个命令行参数,指示程序将执行5个任务中的哪一个。在程序的生命周期内,在运行请求的任务时,我监视程序的内存利用率。对于任务1-4,当我使用-Xmx512m时,我观察到在完成之前内存利用率上升到大约512m。当我使用-Xmx1024m时,在完成之前,内存利用率上升到大约1024m,而它本可以只使用512m。@Raihan对此我可以想到两件事。您正在查看未交换的内存。或者,当您为GC提供更多内存时,它的运行没有那么积极,因此它将性能置于内存使用之上。如果它意识到即将耗尽内存,它将尝试释放尽可能多的悬空引用。如果它有足够的内存,它可以让它们单独运行一段时间。@Raihan如果你必须坚持使用JVM,请找到在所有情况下都应该运行的最大内存量。然后建议系统使用system.GC()进行GC。在-Xmx1024m示例中,调用System.gc(),然后查看您的使用率是否更高。还要记住读取正确的内存值。仅仅因为JVM释放了所有内存并不意味着操作系统现在就愿意从进程中拿走所有内存。有没有办法建议垃圾收集器不要等到堆的所有-Xmx量都用完后再启动,而是在分配了
X
新内存量时开始?有一大堆标志可以使用:我不太确定其中一些标志的影响。