67

鉴于这两个命令

A:

$ java -Xms10G -Xmx10G myjavacode input.txt

乙:

$ java -Xms5G -Xmx5G myjavacode input.txt

我有两个问题:

  1. 由于命令 A 为其参数保留了更多内存,所以 A 会比 B 运行得更快吗?
  2. 对我的程序的运行过程和输出有何影响-Xmx-Xms
4

8 回答 8

166

-Xmx参数定义了 JVM 堆可以达到的最大内存大小。您必须非常了解您的程序并查看它在负载下的性能并相应地设置此参数。如果您的程序的堆内存达到最大堆大小,较低的值可能会导致OutOfMemoryExceptions或性能非常差。如果您的程序在专用服务器上运行,您可以将此参数设置得更高,因为它不会影响其他程序。

-Xms参数设置 JVM 的初始堆内存大小。这意味着当您启动程序时,JVM 将立即分配此内存量。如果您的程序从一开始就消耗大量堆内存,这将非常有用。这避免了 JVM 不断增加堆并在那里获得一些性能。如果您不知道此参数是否对您有帮助,请不要使用它

总之,这是一个折衷方案,您必须仅根据程序的内存行为来决定。

于 2009-06-25T13:22:02.860 回答
24

这取决于您的 java 使用的 GC。并行 GC 可能在更大的内存设置上工作得更好——不过我不是这方面的专家。

一般来说,如果你有更大的内存,那么它需要被 GC-ed 的频率就越低 - 有很多垃圾空间。但是,当涉及到 GC 时,GC 必须在更多内存上工作——这反过来可能会更慢。

于 2009-06-25T13:12:29.650 回答
4

我发现在某些情况下过多的内存会减慢程序的速度。

例如,我有一个基于休眠的转换引擎,随着负载的增加,它开始缓慢运行。事实证明,每次我们从数据库中获取一个对象时,hibernate 都会检查内存中是否有不再使用的对象。

解决方案是从会话中逐出旧对象。

斯图尔特

于 2012-01-03T21:33:54.240 回答
3
  1. 分配始终取决于您的操作系统。如果分配太多内存,最终可能会将部分加载到交换中,这确实很慢。
  2. 您的程序运行得更慢还是更快取决于 VM 必须处理和清理的引用。GC 不必扫描分配的内存来查找废弃的对象。它通过引用映射知道它的对象和它们分配的内存量。所以清扫只取决于你的物体的大小。如果您的程序在这两种情况下的行为相同,则唯一的性能影响应该是对 VM 启动、VM 尝试分配操作系统提供的内存以及如果您使用交换(这再次导致 1.)
于 2009-06-25T14:14:42.677 回答
3

-Xms 和 -Xmx 的各种设置之间的速度权衡取决于运行 Java 应用程序的应用程序和系统。它还取决于您使用的 JVM 和其他垃圾收集参数。

这个问题已有 11 年的历史,从那时起 JVM 参数对性能的影响变得更加难以提前预测。因此,您可以尝试不同的值并查看对性能的影响,或者使用像Optimizer Studio这样的免费工具,它会自动找到最佳 JVM 参数值。

于 2020-08-17T15:28:14.660 回答
2

很难说内存分配将如何影响您的速度。这取决于 JVM 使用的垃圾收集算法。例如,如果您的垃圾收集器需要暂停进行完整收集,那么如果您的内存比实际需要的多 10 个,那么收集器将有 10 个更多的垃圾需要清理。

如果您使用的是 java 6,您可以使用 jconsole(在 jdk 的 bin 目录中)附加到您的进程并观察收集器的行为。一般来说,收集器非常聪明,您不需要进行任何调整,但如果您有需要,可以使用许多选项来进一步调整收集过程。

于 2009-06-25T13:20:22.800 回答
1
> C:\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
-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.

这些-X选项是非标准的,如有更改,恕不另行通知。

(复制粘贴)

于 2013-07-01T08:59:53.843 回答
1

这一直是我在处理我的一个应用程序时遇到的问题,该应用程序为每个请求创建了大量线程。

所以这是一个非常好的问题,这有两个方面:
1. 我的 Xms 和 Xmx 值是否应该相同
       - 大多数网站甚至 oracle 文档都建议它是相同的。但是,我建议在这些值之间留出大约 10-20% 的缓冲区,以便为您的应用程序提供一个调整堆大小的选项,以防突然出现高流量峰值或偶然的内存泄漏。

2. 我是否应该以较小的堆大小启动我的应用程序
       - 所以事情就是这样 - 无论你使用什么 GC 算法(甚至 G1),大堆总是有一些权衡。目标是根据延迟和吞吐量确定应用程序的行为,以允许 GC 暂停的堆大小。
              - 例如,如果您的应用程序有很多线程(每个线程在本机内存中而不是在堆中都有 1 MB 堆栈)但不占用大量对象空间,那么我建议使用较低的 Xms 值。
              - 如果您的应用程序创建了大量线程数增加的对象,则确定您可以设置的 Xms 值以容忍那些 STW 暂停。这意味着确定您可以容忍的传入请求的最大响应时间,并根据调整最小堆大小。

于 2018-12-22T22:52:55.783 回答