When you are using JVM in 32-bit mode, the maximum heap size that can be allocated is 1280 MB. So, if you want to go beyond that, you need to invoke JVM in 64-mode.
You can use following:
$ java -d64 -Xms512m -Xmx4g HelloWorld
where,
- -d64: Will enable 64-bit JVM
- -Xms512m: Will set initial heap size as 512 MB
- -Xmx4g: Will set maximum heap size as 4 GB
You can tune in -Xms and -Xmx as per you requirements (YMMV)
A very good resource on JVM performance tuning, which might want to look into: http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html
Answer from mohitsoni on Stack OverflowWhen you are using JVM in 32-bit mode, the maximum heap size that can be allocated is 1280 MB. So, if you want to go beyond that, you need to invoke JVM in 64-mode.
You can use following:
$ java -d64 -Xms512m -Xmx4g HelloWorld
where,
- -d64: Will enable 64-bit JVM
- -Xms512m: Will set initial heap size as 512 MB
- -Xmx4g: Will set maximum heap size as 4 GB
You can tune in -Xms and -Xmx as per you requirements (YMMV)
A very good resource on JVM performance tuning, which might want to look into: http://java.sun.com/javase/technologies/hotspot/gc/gc_tuning_6.html
Get yourself a 64-bit JVM from Oracle.
java - how to choose the jvm heap size? - Stack Overflow
Essential JVM Heap Settings: What Every Java Developer Should Know
Strategies for predicting JVM heap dump size
Large or small heap size
Videos
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.
JVM Heap optimization in newer Java versions is highly advanced and container-ready. This is great to quickly get an application in production without having to deal with various JVM heap related flags. But the default JVM heap and GC settings might surprise you. Know them before your first OOMKilled encounter.