Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Encourage the JVM to GC rather than grow the heap?

Tags:

(Note that when I say "JVM", I really mean "Hotspot", and I'm running the latest Java 1.6 update.)

Example situation:

My JVM is running with -Xmx set to 1gb. Currently, the heap has 500mb allocated, of which 450mb is used. The program needs to load another 200 mb on the heap. Currently, there is 300mb worth of "collectable" garbage in the heap (we'll assume it's all in the oldest generation.)

Under normal operation, the JVM will grow the heap to 700 mb or so, and garbage collect when it gets around to it.

What I would like in that situation is for the JVM to gc first, then allocate the new stuff, so that we end up with the heap size staying at 500mb, and the used heap at 350mb.

Is there a JVM parameter combo that does that?

like image 905
Electrons_Ahoy Avatar asked Mar 18 '11 17:03

Electrons_Ahoy


People also ask

Can you force JVM to do garbage collection?

Call System.gc() anywhere in their code to instruct the JVM to prioritize garbage collection. When a developer calls this method -- and there isn't an extreme load on the JVM -- a Java GC cycle will happen within seconds.

What triggers JVM GC?

The JVM controls the Garbage collector, it decides when to run the Garbage Collector. It will run the GC when it realizes that the memory is running low or an object become eligible for GC when no live thread can access it.

Does increasing heap size improve performance?

You can improve performance by increasing your heap size or using a different garbage collector. In general, for long-running server applications, use the J2SE throughput collector on machines with multiple processors (-XX:+AggressiveHeap) and as large a heap as you can fit in the free memory of your machine.

What is GC in JVM?

Java garbage collection is the process by which Java programs perform automatic memory management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM for short. When Java programs run on the JVM, objects are created on the heap, which is a portion of memory dedicated to the program.


2 Answers

You could try specifying -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio to control heap expansion and shrinking:

  • -XX:MinHeapFreeRatio - when the percentage of free space in a generation falls below this value the generation will be expanded to meet this percentage. Default is 40.
  • -XX:MaxHeapFreeRatio - when the percentage of free space in a generation exceeded this value the generation will shrink to meet this value. Default is 70.

You might also want to experiment with concurrent GC by specifying -XX:+UseConcMarkSweepGC. Depending on your application it could keep the heap size lower at the cost of additional CPU cycles.

The JVM is otherwise going to use the memory you specify as available when it's optimal do to so. You could specify a lower amount like -Xmx768m to keep it contained and it might run fine, although you would increase your risk of running out of memory in a heavy load scenario. Really the only way to use less memory overall is to write code that uses less memory :)

like image 166
WhiteFang34 Avatar answered Jun 13 '23 01:06

WhiteFang34


Update Java 15 added two more collectors. Some of the relevant options in ZGC are:

  • -XX:+UseZGC enable ZGC
  • -XX:+ZProactive and -XX:+ZUncommit Both are enabled by default. ZGC will proactively try to both free garbage objects and to release the freed memory to the OS. The rest of the options tweak how aggressively it's done.
  • -XX:ZCollectionInterval=seconds How often the GC runs. Set to a few seconds to ensure that garbage is cleaned up as quickly as possible. (By default it's 0, ie no guarantee the GC will run.)
  • -XX:ZUncommitDelay=seconds Sets the amount of time (in seconds) that heap memory must have been unused before being uncommitted. By default, this option is set to 300 (5 minutes). Set a lower value to get back the memory more quickly
  • -XX:SoftMaxHeapSize The GC will fire more often whenever the application uses more memory than this limit. (This is probably the answer the OP is looking for.)
  • -XX:SoftRefLRUPolicyMSPerMB Not sure how often this option is relevant, but it controls how long some cached objects remain in memory.

Original Answer There are four (actually, five) different garbage collectors in HotSpot, and your options are different for each one.

  • The serial collector has -XX:MinHeapFreeRatio and -XX:MaxHeapFreeRatio, which let you more or less directly control the behavior. I don't have much experience with the serial collector however.
  • The parallel collector (-XX:+UseParallelOldGC) has -XX:MaxGCPauseMillis=<millis> and -XX:GCTimeRatio=<N>. Setting a lower maximum pause time generally causes the collector to make the heap smaller. However, if the pause time is already small the heap won't become smaller. OTOH, if the max pause time is set too low, the application may spend all of its time collecting. Setting a lower gc time ratio also generally makes the heap smaller. You are telling the gc that you're willing to dedicate more CPU time to collection in return for a smaller heap. However, this is just a hint and may have no effect. In my opinion, the parallel collector is close to untunable for the purpose of minimizing the heap's size. This collector works better (it tunes itself) if you let it run for a while and the application's behavior stays constant.
  • The CMS collector (-XX:+UseConcMarkSweepGC) generally requires a larger heap to accomplish its main goal of low pause time, so I won't discuss it.
  • The new G1 collector (-XX:+UseG1GC) isn't as brain-dead as the older collectors. I find that it chooses a smaller heap size on its own. It has a lot of tuning options, although I've only begun to study them. -XX:InitiatingHeapOccupancyPercent, -XX:G1HeapWastePercent, -XX:G1ReservePercent and -XX:G1MaxNewSizePercent may be of interest.

Take a look at the list of java flags.

like image 22
Aleksandr Dubinsky Avatar answered Jun 13 '23 00:06

Aleksandr Dubinsky