This is the 11th day of my participation in the August More Text Challenge
Before we get to memory allocation and GC strategy, let’s talk about generational collection theory. Separate to collect is a set of symbols that most programs operate as a rule of thumb based on two hypotheses:
- The Weak Generational Hypothesis: the overwhelming majority of subjects were born and died.
- The Strong Generational Hypothesis: the more times an object survives a garbage collection, the less likely it is to die.
Together, these two generational hypotheses underlie a consistent design principle for several common garbage collectors: the collector should divide the Java heap into different regions and then store the collected objects in different regions based on their age (that is, the number of times the object has survived the garbage collection process).
The terms associated with garbage collection are:
- Minor /Young GC: Refers to a garbage collector that targets only the new generation.
- Major GC: Garbage collection that targets only Old GC. Currently, only the CMS collector has the behavior of collecting older generations separately.
- Mixed GC: Garbage collection that aims to collect the entire new generation and parts of the old generation. Currently, only the G1 collector has this behavior.
- Full GC: Collects the entire Java heap and method area garbage collection.
Memory allocation policy
Objects are allocated in Eden area first
In most cases, objects are allocated within the Eden region of the new generation. When the Eden area does not have enough space to allocate, the virtual machine will initiate a Minor GC.
Big object goes straight to the old age
Large objects are objects that require contiguous memory space. JVM parameters – XX: PretenureSizeThreshold can set the size of a large object, if the object is more than set size goes straight to the old age, not the young generation, this parameter in Serial and ParNew only effective under two collector. Objects that exceed the set value go straight to the old age to avoid inefficient copying when allocating memory for large objects.
Long-lived objects enter the old age
Since virtual machines use generational collection to manage memory, memory collection must be able to identify which objects should be placed in the new generation and which objects should be placed in the old generation. To do this, the virtual machine gives each object an object Age counter. If the object survives after Eden is born and after the first MinorGC and can be accommodated by Survivor, it is moved to Survivor space and the object age is set to 1. Each time an object survives MinorGC in a Survivor, its age increases by one year, and when it reaches a certain age (15 by default), it is promoted to the old age. The age threshold for the object to be promoted to the old age can be set by using -xx :MaxTenuringThreshold.
Object dynamic age judgment
If the total size of a batch of objects in the Survivor region is greater than 50% of the memory size of this Survivor region, then the objects that are greater than or equal to the maximum age of the batch of objects can directly enter the old age. For example, there are a batch of objects in the Survivor region. When the total number of age objects 1+ 2+ n exceeds 50% of the Survivor area, all objects older than n are put into the old age. This rule is actually to hope that those objects that are likely to be long-term survival, as early as possible into the old age. Object dynamic age determination is usually triggered after Minorgc.
After Minor GC, the Survivor zone of the surviving object cannot be saved
In this case, some of the surviving objects are moved to older ages, and some may still be in Survivor zones.
Old age allocation guarantee mechanism
Young generation each Minor Before GC, the JVM will calculate the free space of the old generation. If the free space is less than the sum of the size of all existing objects in the young generation (including garbage objects), it will see if a ** -xx: -handlePromotionFailure **(jdk1.8 default) parameter is set. It looks to see if the available memory size of the old age is greater than the average size of objects that entered the old age after each previous Minor GC. If the result of the previous step is less than or the previous parameter is not set, then a Full GC will be triggered, and garbage will be collected for both the old and young generations. If there is still not enough space to store new objects, an OOM will occur. Of course, Full GC will also be triggered if the size of the remaining objects that need to be moved to the old age after the Minor GC is still larger than the available space of the old age, and OOM will also occur if there is still no space left for the objects that survived the Minor GC.
The default value of Eden and Survivor zone is 8:1:1
A large number of objects are allocated in Eden area. When Eden area is full, Minor GC will be triggered. More than 99% of the objects may be garbage collected and the remaining objects will be moved to the empty survivor area. The Eden area and Survivor are collected by garbage objects, and the remaining surviving objects are moved to another empty survivor area at one time. Since the objects of the new generation all die overnight and survive for a very short time, the default ratio of 8:1:1 by JVM is quite appropriate, so Eden area should be as large as possible. The survivor zone is sufficient. ** -xx :+UseAdaptiveSizePolicy by default, this will cause the ratio to automatically change **. If you do not want this ratio to change, you can set the parameter -xx: -useadaptivesizePolicy.