当启动JVM时,-Xms和-Xmx参数是什么?

1438
请解释JVM中XmsXmx参数的用途。它们的默认值是什么?

2
使用 -Xmx128m -Xms64m 时,它的 RES 内存峰值大约为 275m,但是使用 -Xmx128m -Xms128m 时,它的 RES 内存峰值大约为 550m。使用 Java 8。最好的方法是强制进行 GC 并观察发生了什么... - Christophe Roussy
5
纯粹出于好奇,275米和550米是如何计算出来的? - Manuel Jordan
默认值请参见 https://dev59.com/1G445IYBdhLWcg3w3Nsf - rogerdpack
5个回答

1838

标记Xmx指定Java虚拟机(JVM)的最大内存分配池,而Xms则指定初始内存分配池。

这意味着您的JVM将以Xms的内存启动,并能够使用最多Xmx的内存。例如,像下面这样启动JVM将使用256 MB的内存启动,并允许进程使用高达2048 MB的内存:

java -Xms256m -Xmx2048m

内存标志也可以以不同的大小指定,例如千字节、兆字节等。

-Xmx1024k
-Xmx512m
-Xmx8g
Xms 标志没有默认值,而 Xmx 通常具有 256 MB 的默认值。这些标志的常见用途是当你遇到 java.lang.OutOfMemoryError 时使用它们。

在使用这些设置时,请记住这些设置是针对 JVM 的 的,并且 JVM 可以并且将使用比分配给堆的大小更多的内存。从 Oracle 文档 中可以了解到:

请注意,JVM 使用的不仅仅是堆内存。例如,Java 方法、线程堆栈和本地句柄分配在与堆分离的内存中,以及 JVM 内部数据结构。


24
当内存使用量超过Xmx时,我们会遇到JVM内存溢出异常。 - Pankaj
76
是的,没错。当它试图超过最大内存限制时,虽然它可能会回收垃圾以尝试释放足够的内存,但如果仍然没有足够的内存来满足请求并且堆已经达到最大大小,就会出现 "OutOfMemoryError" 错误。 - David Conrad
2
当我使用ForkJoin模块时,我的电脑会因为它占用了太多内存而崩溃。在OpenJDK上,默认情况下是否可能没有内存上限? - Christophe De Troyer
11
Does java -Xmx 1G mean 1 GB or 2^30 B?中澄清了一个问题,即通过-Xms256m表达启动内存大小的明确方式是“256 MiB”,而不是“256 MB”,因为它是按二进制幂计算的,而不是按十的幂计算。请参见https://en.wikipedia.org/wiki/Binary_prefix。此外,由于一些不能使用的空间被留出来作为额外的Survivor空间池,根据`Runtime.getRuntime().maxMemory()`,实际可用的内存量少于通过`-Xmx`指定的值。 - nealmcb
2
一份有用的关于堆大小常见错误的指南:http://blog.paulgu.com/java/6-common-errors-in-setting-java-heap-size/ - ctrlplusb
显示剩余8条评论

410
运行命令java -X,您将获得所有-X选项的列表:
C:\Users\Admin>java -X
-Xmixed           mixed mode execution (default)
-Xint             interpreted mode execution only
-Xbootclasspath:<directories and zip/jar files separated by ;>
                      set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and zip/jar files separated by ;>
                      append to end of bootstrap class path
-Xbootclasspath/p:<directories and zip/jar files separated by ;>
                      prepend in front of bootstrap class path
-Xdiag            show additional diagnostic messages
-Xnoclassgc       disable class garbage collection
-Xincgc           enable incremental garbage collection
-Xloggc:<file>    log GC status to a file with time stamps
-Xbatch           disable background compilation
-Xms<size>        set initial Java heap size.........................
-Xmx<size>        set maximum Java heap size.........................
-Xss<size>        set java thread stack size
-Xprof            output cpu profiling data
-Xfuture          enable strictest checks, anticipating future default
-Xrs              reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni       perform additional checks for JNI functions
-Xshare:off       do not attempt to use shared class data
-Xshare:auto      use shared class data if possible (default)
-Xshare:on        require using shared class data, otherwise fail.
-XshowSettings    show all settings and continue
-XshowSettings:all         show all settings and continue
-XshowSettings:vm          show all vm related settings and continue
-XshowSettings:properties  show all property settings and continue
-XshowSettings:locale      show all locale related settings and continue

-X选项是非标准的,可能随时更改而不另行通知。

我希望这可以帮助您理解XmsXmx以及其他最重要的事情。 :)


29

-Xms 是启动时的初始堆大小,但是在工作过程中,由于用户不活跃或GC迭代,堆大小可能会小于-Xms。这不是最小所需堆大小。

-Xmx 是最大堆大小。


3
请详细说明“由于用户不活动或GC迭代”是什么意思?那么,初始堆大小和最小堆大小之间有什么区别? - Tony
今天我才意识到,-Xms并不表示最小所需堆内存大小。我们正在一台拥有256 GB RAM的机器上运行一个设置了-Xms为200 GB的Java进程。目前该进程只消耗了10 GB的内存,这是因为该进程目前没有进行太多活动。所以,这个答案确实证实了这一点,但我仍在寻找相关文档/来源。非常感谢! - asgs
2
有三种堆大小:已使用、已分配和最大。已使用的堆大小可以小于-Xms,但已分配的堆大小(即通过malloc()从操作系统分配的)始终至少为-Xms。一些操作系统会愉快地malloc()更多的内存,希望并非所有应用程序都实际使用它们malloc()的所有内容,因此“已分配”是一个相对的术语。 - toolforger

15

8
针对除JRockit以外的其他JVM,请参考此帖子以确定您的JVM的默认Xmx/Xms值:https://dev59.com/1G445IYBdhLWcg3w3Nsf - Ogre Psalm33

15

您可以在IDE中进行指定。例如,对于Eclipse,请在运行配置VM参数中输入-Xmx800m -Xms500m.

输入图像描述


在OSX上的RubyMine中,它位于帮助菜单>编辑自定义VM选项。 - Jon Schneider
29
这并没有回答问题。问题是关于它们的用途,而不是如何设置它们。 - Captain Man

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