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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1043817/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:39:08  来源:igfitidea点击:

Speed tradeoff of Java's -Xms and -Xmx options

javaperformancejvm-arguments

提问by neversaint

Given these two commands

鉴于这两个命令

A:

A:

$ java -Xms10G -Xmx10G myjavacode input.txt

B:

乙:

$ java -Xms5G -Xmx5G myjavacode input.txt

I have two questions:

我有两个问题:

  1. Since command A reserves more memory with its parameters, will A run faster than B?
  2. How do -Xmxand -Xmsaffect the running process and the output of my program?
  1. 既然命令 A 为其参数保留了更多的内存,那么 A 会比 B 运行得更快吗?
  2. 如何-Xmx-Xms影响我的程序的运行过程和输出?

采纳答案by akarnokd

It depends on the GC your java is using. Parallel GCs might work better on larger memory settings - I'm no expert on that though.

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

In general, if you have larger memory the less frequent it needs to be GC-ed - there is lots of room for garbage. However, when it comes to a GC, the GC has to work on more memory - which in turn might be slower.

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

回答by pfranza

It is difficult to say how the memory allocation will affect your speed. It depends on the garbage collection algorithm the JVM is using. For example if your garbage collector needs to pause to do a full collection, then if you have 10 more memory than you really need then the collector will have 10 more garbage to clean up.

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

If you are using java 6 you can use the jconsole (in the bin directory of the jdk) to attach to your process and watch how the collector is behaving. In general the collectors are very smart and you won't need to do any tuning, but if you have a need there are numerous options you have use to further tune the collection process.

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

回答by bruno conde

The -Xmxargument defines the max memory size that the heap can reach for the JVM. You must know your program well and see how it performs under load and set this parameter accordingly. A low value can cause OutOfMemoryExceptionsor a very poor performance if your program's heap memory is reaching the maximum heap size. If your program is running in dedicated server you can set this parameter higher because it wont affect other programs.

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

The -Xmsargument sets the initial heap memory size for the JVM. This means that when you start your program the JVM will allocate this amount of memory instantly. This is useful if your program will consume a large amount of heap memory right from the start. This avoids the JVM to be constantly increasing the heap and can gain some performance there. If you don't know if this parameter is going to help you, don't use it.

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

In summary, this is a compromise that you have to decide based only in the memory behavior of your program.

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

回答by cafebabe

  1. Allocation always depends on your OS. If you allocate too much memory, you could end up having loaded portions into swap, which indeed is slow.
  2. Whether your program runs slower or faster depends on the references the VM has to handle and to clean. The GC doesn't have to sweep through the allocated memory to find abandoned objects. It knows it's objects and the amount of memory they allocate by reference mapping. So sweeping just depends on the size of your objects. If your program behaves the same in both cases, the only performance impact should be on VM startup, when the VM tries to allocate memory provided by your OS and if you use the swap (which again leads to 1.)
  1. 分配始终取决于您的操作系统。如果分配太多内存,最终可能会将部分加载到交换中,这确实很慢。
  2. 你的程序运行得更慢还是更快取决于 VM 必须处理和清理的引用。GC 不必扫描分配的内存来查找废弃的对象。它知道它的对象以及它们通过引用映射分配的内存量。所以清扫只取决于你的物体的大小。如果您的程序在这两种情况下的行为都相同,那么唯一的性能影响应该是在 VM 启动时,当 VM 尝试分配您的操作系统提供的内存时,如果您使用交换(这再次导致 1)。

回答by SaSConsul

I have found that in some cases too much memory can slow the program down.

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

For example I had a hibernate based transform engine that started running slowly as the load increased. It turned out that each time we got an object from the db, hibernate was checking memory for objects that would never be used again.

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

The solution was to evict the old objects from the session.

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

Stuart

斯图尔特

回答by Virus

> 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.

The -Xoptions are non-standard and subject to change without notice.

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

(copy-paste)

(复制粘贴)

回答by user1540256

This was always the question I had when I was working on one of my application which created massive number of threads per request.

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

So this is a really good question and there are two aspects of this:
1. Whether my Xms and Xmx value should be same
       - Most websites and even oracle docs suggest it to be the same. However, I suggest to have some 10-20% of buffer between those values to give heap resizing an option to your application in case sudden high traffic spikes OR a incidental memory leak.

2. Whether I should start my Application with lower heap size
       - So here's the thing - no matter what GC Algo you use (even G1), large heap always has some trade off. The goal is to identify the behavior of your application to what heap size you can allow your GC pauses in terms of latency and throughput.
              - For example, if your application has lot of threads (each thread has 1 MB stack in native memory and not in heap) but does not occupy heavy object space, then I suggest have a lower value of Xms.
              - If your application creates lot of objects with increasing number of threads, then identify to what value of Xms you can set to tolerate those STW pauses. This means identify the max response time of your incoming requests you can tolerate and according tune the minimum heap size.

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

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