Starting memory allocation for JVM
I am starting to use a parameter -Xmx
in the command java
to allow my processes to use a little more memory (256 MB, although I think I am currently using less than 128 MB). I also noticed an option -Xms
to start memory with a default of 2Mb. What should I set for this value and why?
a source to share
The argument -Xmx
specifies the maximum size of memory that the heap can reach for the JVM. You should know your program well and see how it works under load and set this parameter accordingly. A low value can cause OutOfMemoryException
or very poor performance if your program's heap memory reaches the maximum heap size. If your program is running on a dedicated server, you can set this parameter above because it does not affect other programs.
The argument -Xms
sets the initial and minimum heap memory for the JVM. This means that when you run your program, the JVM will instantly allocate that amount of memory. This is useful if your program will consume a lot of heap memory from the start. This avoids the JVM requiring the heap size to grow regularly and so you might get some performance there. If you don't know if this option will help you, do not use it.
It is good practice with server-side Java applications like Resin to set minimum heap sizes -Xms
and maximum -Xmx
to the same value. You can set the value to 256 or 512 MB.
a source to share
The heap size must be "right" for your application to find, although this is not easy. If it is too small, you will run out of memory, if you are large unnecessary memory and run the risk of having long GC pauses. When things go wrong (and they always go wrong), the more heap you have, the more heap you have to debug, and the longer any leaks will take to prove themselves.
Ideally, I would set the -Xms
size that I think the application should execute, and -Xmx
a value larger than that (but not too large). Always include verbose garbage collection and heap usage graphs to check the values set.
When I draw the heap, I look at the number of collections being collected and the type. It's important not to have too much. However, it is also important not to have a heap so huge that it is not enough, because when they happen (and full gc is inevitable) they will hurt. Ideally, a regular set of well-distributed gcs with very low pause times is required.
This means that for 32 bit Windows it -Xms
should be the same as, -Xmx
because Java (leaving jrockit aside) needs contiguous memory and the Windows memory map is fragmented, so it pays to get and lock the heap as much as possible earlier.
a source to share
Xmx is the upper limit of the memory pool. Xms is the starting size. It's all there. The appropriate size for each will depend on the complexity of your application. The main benefit of setting the initial size above 2MB would simply be that the JVM would spend less time requesting more memory from the OS. If you set the upper limit to 256MB, the original 32MB-64MB size wouldn't be unreasonable for most enterprise applications.
More details here: http://java.sun.com/j2se/1.5.0/docs/tooldocs/windows/java.html
a source to share
How do I set this value and why?
Depending on your application, of course.
If you know that your application is initially consuming up to 64 MB in the first minute and then using the default (2 MB) it will make the VM request memory multiple times until it reaches that 64 MB. These memory requests will slow down your application a bit, because the garbage collector may run multiple times trying to free up space before the VM requests more.
If you already know what you will use as the starting 64 mb, using the parameter -Xms
, you can allocate this memory in advance.
If you are consuming 128MB and you have enough available memory, you can use it java -Xms128m
and not worry about asking for more memory for a long time.
But again, it depends on what your application is doing, how memory is used when needed. etc.
a source to share