As pcalcao mentioned, the JVM tells you that it spends too much time collecting garbage and doesn't do enough real work, so itās just going to help out.
This is a kind of safety valve to avoid the case when you actually do not have enough memory, but close enough so that you really are not moving forward. I will not upset this point - this answer contains much more details, but I will talk about a few things that may be applicable to your case:
This is more likely if you SoftReference will cache things - as the heap grows to its maximum size, these links are cleared and possibly re-regenerated (depending on whether your key cycle concerns), which leads to some bad behavior when the GC happens permanently, but always restores enough memory to continue, because it can clear some soft links - even the JDK suffers from this because they use this type of caching in their Locale classes.
You can disable this behavior if you really want to use -XX: -UseGCOverheadLimit. However, the problem in question is real - you spend less than 2% of your work environment on doing real work.
Where do you print these memory values? Depending on how your program is structured, it can generate a lot of garbage and use most of the heap in some internal loop, but in the place where you put your output to the diagnostics, garbage that has been recovered. -verbose: gc can give you a much better picture of the actual behavior of the GC.
source share