What i usually do concerning the jvm heap size is setting the max value really high to avoid the infamous OutOfMemoryException.
However, this strategy (or lack of strategy) doesn't seem to be really smart. :-).
My question is how to choose the min and max values, and the difference between the two (should max-min be small or big?). For instance, from here:
if the initial heap is too small, the Java application startup becomes slow as the JVM is forced to perform garbage collection frequently until the heap has grown to a more reasonable size. For optimal startup performance you should set the initial heap size to the same as the maximum heap size.
thanks.
You can verify that the JVM is using the increased Java heap space: Open a terminal window. Review the command output. The argument beginning with "-Xmx" will give you the value of the current Java heap space.
The Java™ virtual machine (JVM) heap size setting directly relates to how many server instances can be started within a dynamic cluster on a specific node. You might need to modify the JVM heap size setting based on your environment configuration. The default value is 256 MB.
The max JVM heap size limit has been removed since we moved to completely 64 bit releases. As such you are now limited by the OS and/or machine. The theoretical limit is 2^64 bytes, which is 16 exabytes (1 exabyte = 1024 petabytes, 1 petabyte = 1024 terabytes).
My question is how to choose the min and max values, and the difference between the two (should max-min be small or big?)
Short answer: don't guess, profile your application.
jconsole can give you useful high-level data such as a feeling for the main resident set vs. the transient data that we normally allocate and garbage collect. What you'll see if you look at the memory tab of that display is usually something like a sawtooth. The lower corner of the sawteeth is about where I would normally set the heap minimum whereas I would use the peak or slope of the sawteeth to experiment with a heap maximum. If your teeth are very steep, you might consider a big heap just to delay the garbage collection. However, if they aren't, you could try a smaller heap maximum to see if that might leave more resources for other processes on your machine (for example).
You should also consider the server VM as that will cause different garbage collection behavior.
All that said, you should also use a more detailed tool such as jvisualvm to profile the memory usage of your process. It's possible that you have a memory leak or greedy allocator that you could tune or eliminate. That would completely change your heap needs.
You should enable GC logging and check to see where your OOM is ocurring.
-verbose:gc -Xloggc:gc.log -XX:+PrintGCTimeStamps -XX:+PrintGCDetails
You may be experiencing perm space limits, adjust via -XX:MaxPermSize=YYYm
Anyway to answer your question, I start with no minimums and set the maximum relatively high. I then graph the gc log and find out where my stead state is; visually choose an above-average size for the various generations. Read it like a financial chart, you'll want to see good spread in the new generations and a consistent growth and collection in the tenured generation. As mentioned also graph your perm space to make sure you're not constantly increasing.
GC tuning is an art, in no way a science.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With