To me, understanding what it really does, means to go the source code. I chose jdk-15.
The best description of this flag is here:
It determines the minimum reserve we should have in the heap to minimize the probability of promotion failure.
Excellent, so this has to do with "promotion failures" (whatever those are). But according to you quote in bold, this has something to do with AdaptiveIHOP also? Well yes, this parameter matters only in AdaptiveIHOP (which is on by default).
Another thing to notice is that G1ReservePercentage has no guarantee to be maintained all the time, it is a best effort.
If you look at how it is used in the very next line:
if (_free_regions_at_end_of_collection > _reserve_regions) {
absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
}
things start to make some sense (for that bold statement). Notice how _reserve_regions are extracted for some computation. G1 will reserve that space for "promotion failures" (we will get to that).
If G1 reserves that space, it means less space is available for actual allocations. So if you "increase this buffer" (you make G1ReservePercent bigger as the quote suggests), your space for new objects becomes smaller and as such the time when GC needs to kick in will come sooner, so the time for when space reclamation needs to happen will come sooner too ("Lower the target occupancy for when to start space-reclamation..."). It is one complicated sentence, but in simple words it means that :
If you increase
G1ReservePercentage, space will be needed to be reclaimed faster (more often GC calls).
Which, to be fair, is obvious. Not that I agree that you should increase that value, but this is what that sentence says.
After a certain GC cycle, be that minor, mixed or major, G1 knows how many regions are free:
_free_regions_at_end_of_collection = _g1h->num_free_regions();
Which of course, is the length of "free list":
return _free_list.length();
Based on this value and _reserve_regions (G1ReservePercent) plus the target pause time (200 ms by default) it can compute how many regions it needs for the next cycle. By the time next cycle ends, there might be a case when there are no empty regions (or the ones that are empty can not take all the live Objects that are supposed to be moved). Where is Eden supposed to move live Objects (Survivor), or, if old region is fragmented - where are live objects supposed to be moved to defragmente? This is what this buffer is for.
It acts as a safety-net (the comments in the code make this far more easier to understand). This is needed in the hopes that it will avoid a Full GC. Because if there are no free regions (or enough) to move live Objects a Full GC needs to happen (most probably followed by a young GC also).
This value is usually known to be small when this message is present in logs. Either increase it, or much better give more heap to the application.
Answer from Eugene on Stack OverflowGarbage collection woes
Garbage Collection is running, but it’s running extremely slow
Insuffecient memory when running hira, confluence and bit.
Memory leak in all servers on pterodactyl 1.11.7
I have a 7.17 cluster that is having severe problems with search and I could really use some advice. It's fairly search heavy, usually 3000-5000 per/sec. The data nodes will start going into frequent GC (young) and soon after I'll start getting search rejections and the downstream clients start breaking.
It's holding 50.5TB (1:1), 26 billion docs across 50 data nodes. The shards are between 35-45GB and each node holds about 30 shards.
The specs on the nodes are N2-himem-8 (we're running on VMs in GCP) which gives me 64GB RAM. The heap is set to 31GB and we're using G1GC garbage collection with the default JVM settings which means GC kicks in at about 23GB usage. The o/s is linux.
I think I've got 3 options, any advice would be appreciated.
-
split the indices and reduce the shard size to 15-20GB, I know there's an overhead to shard management, 20 shards per GB of heap. It's counterintuitive but I've good reason to believe this could help.
-
Tweak the JVM settings. I don't think ConcMarkSweep is recommended for larger heap sizes, so that basically leaves me with reducing the G1ReservePercent to 5 or 10. What are the implications of this ?
-
Increase the heap beyond 31GB and bump up the platforms RAM
I know compressed memory pointers in a JVM aren't effective in larger heaps, *but* I thought that only applied to 32bit JVMs, and we're running 64bit JVMs. Am I wrong ?
Does anybody run elasticsearch with heaps larger than 31GB ?