While reading some notes on performance tuning, I did notice a recommendations while setting memory size:
Java application should size both initial and maximum permanent generation size to the same value since growing or contracting the permanent generation space requires a full GC. Similar suggestion is given while setting the heap size, I.e. -Xmx=-Xms
.
My question is, then why do we have -Xms setting at all?
Also, Why GC gets triggered often if I''ve different value for -Xmx and -Xms, and not when I''ve same size for -Xmx and -Xms.
To add more to my second question, If I start with minimum heap size of 64M and Max 512 M, I believe full GC will not get triggered unless memory utilized by my app reaches 512M.
Similarly If I start with 512M for both -Xmx and -Xms, still JVM will trigger full GC when my app memory use reaches this limit. So why it's advised to set both max and min to the same value?
The setting flags were designed before the VM had generational, incremental collection. In that case complete collections were all there were. In more modern collectors full collections are rare. That's good because incremental collections are normally a few milliseconds, so the UI experience doesn't change. Complete collections of big arenas can take several seconds ore more. Changing the arena size - as the document says - is guarenteed to cause a full collection every time.
The guidance isn't perfect 100% of the time. There are few kinds of apps where allowing the arena to grow is reasonable.