加速Java -Xms和-Xmx选项的权衡

时间:2009-06-25 13:10:36

标签: java performance jvm-arguments

鉴于这两个命令

A:

$ java -Xms10G -Xmx10G myjavacode input.txt

B:

$ java -Xms5G -Xmx5G myjavacode input.txt

我有两个问题:

  1. 由于命令A使用其参数保留更多内存,A运行速度是否比B快?
  2. -Xmx-Xms如何影响正在运行的流程和程序的输出?

8 个答案:

答案 0 :(得分:165)

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

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

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

答案 1 :(得分:21)

这取决于你的java使用的GC。并行GC可能在更大的内存设置上工作得更好 - 虽然我不是那么专家。

一般来说,如果你拥有更大的内存,那么需要进行GC编辑的频率就越低 - 垃圾就有很大的空间。但是,当涉及到GC时,GC必须处理更多内存 - 这反过来可能会更慢。

答案 2 :(得分:4)

我发现在某些情况下,太多内存可能会降低程序速度。

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

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

斯图尔特

答案 3 :(得分:3)

  1. 分配总是取决于您的操作系统。如果你分配了太多的内存,你可能最终将部分加载到交换中,这确实很慢。
  2. 程序运行速度是否较慢或取决于VM必须处理和清理的引用。 GC不必扫描分配的内存来查找被遗弃的对象。它知道它的对象和它们通过引用映射分配的内存量。扫地只取决于物体的大小。如果您的程序在两种情况下都表现相同,那么唯一的性能影响应该是VM启动时,VM尝试分配操作系统提供的内存以及您是否使用交换(再次导致1)。

答案 4 :(得分:2)

很难说内存分配会如何影响你的速度。它取决于JVM使用的垃圾收集算法。例如,如果你的垃圾收集器需要暂停以进行完整的收集,那么如果你有10个以上的内存,那么收集器将有10个垃圾来清理。

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

答案 5 :(得分:2)

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

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

答案 6 :(得分: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选项不符合标准,如有更改,恕不另行通知。

(复制 - 粘贴)

答案 7 :(得分:1)

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

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

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