67

Given these two commands

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 -Xmx and -Xms affect the running process and the output of my program?
skaffman
  • 398,947
  • 96
  • 818
  • 769
neversaint
  • 60,904
  • 137
  • 310
  • 477
  • Does your question relate to some real world issue or it is only a theoretical question? Because if you have that many RAM in a 64 bit system, you might consider changing your algorithms to take advantage of it - e.g. reading/mapping the entire large input.txt into memory and perform operations on that. – akarnokd Jun 25 '09 at 13:31
  • 29
    The answer to these types of questions is always "Benchmark it and find out". – matt b Jun 25 '09 at 14:16
  • 4
    I asked JVM package maintainer and he said: "On Linux, I'm not sure that -Xms does very much unless you have a weird setup. Maybe it allocates without MAP_NORESERVE just to make sure the RAM really is there. But i doubt it." – Ondra Žižka Aug 19 '11 at 17:42

8 Answers8

166

The -Xmx argument 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 OutOfMemoryExceptions or 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.

The -Xms argument 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.

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

bruno conde
  • 47,767
  • 15
  • 98
  • 117
  • you said `If your program is running in dedicated server you can set this parameter higher because it wont affect other programs` I believe if we have multiple process running on same node and if all have their XMx parameters set, no process is going to other process as with Xmx , memory has already been reserved for each process( which can not be used by any other process) Right ? – emilly Sep 23 '16 at 05:09
  • Can you provide your thoughts on http://stackoverflow.com/questions/39652282/impact-of-heap-parameters-on-gc-performance and http://stackoverflow.com/questions/39652282/impact-of-heap-parameters-on-gc-performance ? Thanks in advance – emilly Sep 23 '16 at 05:11
25

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.

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.

akarnokd
  • 69,132
  • 14
  • 157
  • 192
  • @kd304: So if my CPU has large RAM (say 10GB), and let say that is enough for my app to run. Do you mean the less memory as in Xmx/Xms param we use the faster my code will run? – neversaint Jun 25 '09 at 13:19
  • @kd304: btw, how can I check the GC of my java I am using? – neversaint Jun 25 '09 at 13:20
  • 1
    Hard to say as performance depends on many things. I would say you could find a balance between the memory size and the GC runtime cost. Unfortunately, I don't know where you could check what kind of GC is default for your java version. If you want you can even change the GC's type via command line parameters. – akarnokd Jun 25 '09 at 13:27
  • 3
    Overall time spent on GC does NOT increase with the amount of RAM, unless you have a pathological case with lots of full GCs. The usual concern with lots of RAM is that it can lead to no full GC being performed for a long time, followed by the app locking up while it finally performs the GC it has deferred for so long. – Michael Borgwardt Jun 25 '09 at 14:37
  • 3
    @Michael Borgwardt: I thought I described the same thing as your 2nd sentence. – akarnokd Jun 25 '09 at 14:45
  • May I ask the reason for the downvote so I can learn from it? – akarnokd Jun 25 '09 at 22:12
  • 9
    Erm. CPUs do have random access memory. It's called level 1 and level 2 cache. – stu Mar 27 '13 at 15:31
4

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.

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

Stuart

SaSConsul
  • 298
  • 2
  • 9
3
  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.)
cafebabe
  • 1,400
  • 8
  • 9
3

The speed tradeoffs between various settings of -Xms and -Xmx depend on the application and system that you run your Java application on. It also depends on your JVM and other garbage collection parameters you use.

This question is 11 years old, and since then the effects of the JVM parameters on performance have become even harder to predict in advance. So you can try different values and see the effects on performance, or use a free tool like Optimizer Studio that will find the optimal JVM parameter values automatically.

Tomer
  • 549
  • 4
  • 9
2

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.

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.

pfranza
  • 3,292
  • 2
  • 21
  • 34
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.

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

(copy-paste)

Ouroborus
  • 16,237
  • 4
  • 39
  • 62
Virus
  • 167
  • 1
  • 11
1

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.

user1540256
  • 151
  • 2
  • 3