1

ZGC runs not often enough. GC logs show that it runs once every 2-3 minutes for my application and because of this, my memory usage goes high between GC cycles (as high as 90%). After GC, it drops to as low as 20%.

How to increase GC run's frequency to run more often?

viji
  • 2,706
  • 5
  • 28
  • 34
  • Why do you want to run the GC more often? You are not running out of free memory. – tgdavies Jul 09 '21 at 22:32
  • The app's traffic pattern varies. 90% usage is not for the peak traffic and during peak traffic, it would hit OOM. – viji Jul 21 '21 at 05:17
  • I'm not sure what "would" means in this context. Do you mean that you *do* get OOM errors, or that because you see 90% heap usage at non-peak times, you are concerned that you *might* get OOM errors at peak times? – tgdavies Jul 21 '21 at 06:26
  • This is a production system and I can't run it with 90% heap usage. It will definitely get OOM had I run it with 90% heap usage because of my estimation of traffic overload. How is that relevant to the question here? – viji Jul 30 '21 at 03:27
  • I don't think you understand what "heap usage" is or what causes OOM.That said, what you probably mean is that you'd like an accurate picture of the true (non-garbage) memory usage. You'd best achieve that by taking a heap dump and analyzing it. Although, running the GC more often is a lot simpler. – Aleksandr Dubinsky Aug 31 '21 at 11:44
  • Do you have a test environment where you can simulate peak loads? – tgdavies Aug 31 '21 at 23:21
  • @AleksandrDubinsky I do understand what heap usage is. My application generates garbage at a higher speed. If the ZGC doesn't run often, it reaches near-full heap faster because of which the application's performance slows down. Running the garbage collector more no. of times collects the garbage faster. Heap memory is not pretouched in my application. – viji Sep 02 '21 at 02:45
  • @tgdavies, the settings posted by the8472 is what I was looking for. – viji Sep 02 '21 at 02:46
  • Ok, then perhaps you don't know what "OOM" means (it's the fatal error condition, not the situation where you're out of free heap and have to wait for GC). Do you have evidence that your app slows down under ZGC? I think I understand your concern now and will post an answer. – Aleksandr Dubinsky Sep 02 '21 at 09:56
  • ZGC uses 90% of the heap because there is still memory to use and there is no need to proactively reclaim the memory. If your application wants to allocate more frequently, the GC would trigger itself more frequently and collect the garbage more quickly. – Quân Anh Mai Dec 27 '22 at 04:36
  • Btw you estimate peak load performance by simulating peak traffic and measure the performance there, extrapolating from non-peak traffic is terrible. – Quân Anh Mai Dec 27 '22 at 04:37

3 Answers3

3

-XX:ZCollectionInterval=N - set maximum gap between collections to N seconds.
-XX:ZUncommitDelay=M - set the delay until unused memory is returned to the OS to M seconds.

the8472
  • 40,999
  • 5
  • 70
  • 122
1

Before tuning the GC, I would recommend to investigate why this is happening. Might have some issue/bug in your application.

[Some notes about GC]

  • -XX:ZUncommitDelay=M (Check if it is supported by your linux kernel)
  • -XX:+ZProactive: Enables proactive GC cycles when using ZGC. By default, this option is enabled. ZGC will start a proactive GC cycle if doing so is expected to have minimal impact on the running application. This is useful if the application is mostly idle or allocates very few objects, but you still want to keep the heap size down and allow reference processing to happen even when there are a lot of free space on the heap.

More details about ZGC config. options can be found:

1

Presently (as of JDK 17), ZGC's primary strategy is to wait until the last possible moment of the heap filling up and then do a collection. Its goals are

  • Avoid unnecessary CPU load by running GC only when it's necessary.
  • Start the GC early enough so that it will finish before the heap actually fills up (since the heap filling up would be bad, leading to a temporary application stall).

It does this by measuring how fast your app is allocating memory, how long the GC takes to run, and predicting at what point it should start the GC. You can find the exact algorithm in the source code.

ZGC also exposes some knobs for running GC more often (ie, proactively), but honestly I don't find them terribly effective. You can find more info in my other answer. G1 does a better job of being proactive, but whether that's good or not depends on your use-case. (It sounds like you care more about throughput than memory usage, so I think you should prefer ZGC's behavior.)

However, if you find that ZGC is making mistakes in predicting when the heap will fill up and that your application really is hitting stalls, please share that info here or on the ZGC mailing list.

Aleksandr Dubinsky
  • 22,436
  • 15
  • 82
  • 99