A couple of years ago we were having problems caused by long GC pauses, so we went to UseConcMarkSweepGC. We're still using that today. (We also use the -server option.)

Unfortunately, it seems like we are generating garbage faster than the GC can clean it up. Eventually, we run out of memory. We don't have a leak and we're not allocating too much memory; we're simply generating too much garbage.

You'd think that the GC would simply pause for as long as it needs to collect more garbage, but I believe the "Concurrent mark and Sweep" collector is designed to avoid long pauses, so if it can't keep up, it exits.

Before I embark on weeks of trial-and-error and tuning, can I get some advice from this community?

Which GC options should I use? I want to minimize long pauses but I also don't want it to quit if it can't keep up. Should I switch to parallel gc? What about the default "ergonomic' options? Thanks in advance for your help.