使用大量内存的Java应用。使用-Xmx?

26

我有一个Java应用程序,在一台16G内存的机器上使用了约15G。我不知道是否应该设置最大堆大小。

如果设置了,JVM会吃掉所有RAM直到达到限制,然后开始垃圾回收并在处理15G堆对象时停止所有操作吗?

如果没有设置,JVM会通过不使用机器上所有可用的RAM来损害性能吗?

我的具体虚拟机是:Java HotSpot(TM) 64-Bit Server VM(build 1.6.0_03-b05,混合模式)。

谢谢!


1
我现在先使用了 -Xms2G -Xmx14G -XX:+UseConcMarkSweepGC。 - Martin Redmond
3个回答

22

-Xmx15G 将最大堆大小设置为15GB。Java只会在运行时分配所需的堆空间。如果您不设置它,它将仅使用默认值。有关默认值的信息,请参见此帖子

-Xms15G 将最小堆大小设置为15GB。这将强制Java在开始执行之前分配15GB的堆空间,无论是否需要。

通常情况下,可以根据JVM的调优设置它们的合适值。


我发现即使你设置了最小值,它通常也不会始终使用该内存,并且在达到最小值之前会执行较小的GC。 - Peter Lawrey
@Peter Java进程将分配它,但JVM可能实际上不会使用它。我不知道GC的启发式算法,但只要有对象需要收集,它就可以自由运行。考虑当Xms == Xmx时,我希望堆使用率永远不会完全达到Xms。Xms是Java从操作系统“mallocs”的数量,与在JVM中运行的应用程序如何使用堆无关。 - Cogsy
如果您正在使用字符串,还有一件事需要添加-XX:+ UseConMarkSweepGC实际上可以在多核机器上加速收集(如果有足够的资源)。此外,由于字符串很可能会很快晋升到旧一代,因此它们确实会消耗大量内存。 - Andrew Scott Evans

13
在Java 6中,默认的最大堆大小由系统内存量确定。根据垃圾收集器人体工程学页面,最大堆大小为:1/4物理内存或1GB的较小值。在J2SE 5.0之前,默认的最大堆大小为64MB。可以使用-Xmx开关来更改最大堆大小。有关用法详细信息,请参见java - Java应用程序启动器文档。

2
请注意,以上内容仅适用于“服务器级”机器。对于Java SE 6,这是一台至少具有2个CPU和至少2GB物理内存的机器(根据http://download.oracle.com/javase/6/docs/technotes/guides/vm/server-class.html)。 - Johan Kaving

0
如果您没有设置最大堆大小(使用-Xmx),默认的最大值不是只有64MB吗?
所以如果您没有设置它,您的应用程序不会因为OutOfMemoryError而失败吗?我对这个问题感到困惑。没有这个开关,您的应用程序如何运行?

我一直使用 -Xmx 15G 运行,运行得很好。我只是想知道告诉 jvm 它有 15G 可以使用是否会影响性能。它会愉快地填满这 15G,然后花费很长时间来处理吗?此外,我不确定应用程序使用了多少内存,因为当我使用 -Xmx 15G 时,它会增长到 15G。 - Martin Redmond
你确定你实际上需要一个15GB的堆大小,而不仅仅是一个疯狂的内存泄漏吗? - matt b
谢谢您的回复。我并不是在考虑内存问题,而是性能问题。我没有遇到OutOfMemoryError。我正在尝试弄清楚是否应该让JVM找到最佳内存策略,还是应该稍微帮助一下它。 - Martin Redmond
@Martin 我不知道你是如何确定你的应用程序占用了15G的空间。如果你使用 -Xmx15G jvm 参数运行它,并且它占用了那么多内存,那并不意味着它实际上需要15G的内存空间。更多的内存意味着GC会很少运行,这将允许应用程序使用更多内存。因此,请尝试将其设置为较低的-Xmx值进行运行,然后检查是否出现 OutOfMemory 异常。如果是,则明显意味着你的应用程序实际上需要更多的内存,否则就不需要。 - Amit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接