Understanding GC Logs

Let’s look at the code example of yesterday’s object saving itself

VM args:-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps  -XX:+PrintGCTimeStamps
Copy the code

We’re talking about one paragraph at a time

2019-12-11T14:38:51.807+0800(GC time +0800): 0.180(GC time +0800): [GC(GC stands for Young GC,Full GC is itself)(system.gc ()) (trigger GC, in this case because system.gc () was called))) [Times: 1424k -> 1424k] [Times: 1424k -> 1424k] [Times: 1424k -> 1424k] [Times: 1424k -> 1424k] User =0.00(CPU time) sys=0.00(CPU time), real=0.00 [2019-12-11t14:38:51.809 + 0800:0.181: [Full GC (System.gc()) [PSYoungGen: 1419K->0K(76288K)] [ParOldGen: 8K->1182K(175104K)] 1427K->1182K(251392K), [Metaspace: 3134K->3134K(1056768K)], 0.0049875secs] [Times: User =0.00 sys=0.00, real=0.00 Complete self redemption! I'm alive! 2019-12-11T14:39:01.816+ 0800:10.188: [GC (system.gc ())] [PSYoungGen: [Times: Times: 328k -> 328K] 328K -> 328k [Times: 328k -> 328k] 328K -> 328k [Times: 328k] Sys =0.00, real=0.00 secs] 2019-12-11t14:39:01.817 + 0800:10.817: [sysgc ())] [PSYoungGen: 592K->0K(76288K)] [ParOldGen: 1190K->1318K(175104K)] 1782K->1318K(251392K), [Metaspace: [Times: user= 0.03sys =0.00, real= 0.03secs] [Times: user= 0.03sys =0.00, real= 0.03secs] Heap PSYoungGen total 76288K, used 3058K [0x000000076b180000, 0x0000000770680000, 0x00000007c0000000) eden space 65536K, 4%, informs [x000000076b180000 0, 0 x000000076b47cb08, 0 x000000076f180000) from space 10752 k, 0% informs [0 x000000076fc00000, 0 x000000076fc00000, 0 x0000000770680000) to space 10752 k, 0% informs [x000000076 x000000076f180000 0, 0 x000000076f180000, 0fc00000) ParOldGen total 175104K, used 1318K [0x00000006c1400000, 0x00000006cbf00000, 0x000000076b180000) object space 175104K, 0%, informs [x00000006c1400000 0, 0 x00000006c1549bf0, 0 x00000006cbf00000) Metaspace informs the 3789 k, capacity 4540 k, committed 4864K, reserved 1056768K class space used 413K, capacity 428K, committed 512K, reserved 1048576KCopy the code
  • Young GC
  • Full GC

Garbage collector parameters Summary (long-term update)

parameter describe
UseSerialGC Default value for VMS running in Client mode. After this function is enabled, the Serial and Serial Old collectors are used to reclaim memory
UseParNewGC When this switch is turned on, the collector combination of ParNew + Serial Old is used for memory reclamation
UseConcMarkSweepGC When this switch is turned on, the collector combination of ParNew+ CMS + Serial Old is used for memory reclamation. The Serial Old collector will be used as a fallback collector in the event of Concurrent Mode Failure of the CMS collector
UseParallelGC The vm operates in Server mode by default. Use the Parallel Scavenge + Serial Old (PS Mark Sweep) collector to reclaim memory
UserParallelOldGC When this switch is turned on, recycle memory using a combination of the Parallel Avenge + Parallel Old collector
SurvivorRatio Capacity ratio between Eden region and Survivor region in the new generation. The default value is 8, indicating Eden: Survivor = 8:1
PretenureSizeThreshold Directly to the size of the object in the old age. If this parameter is set, objects larger than this parameter will be directly allocated in the old age
MaxTenuringThreshold Promotion to the target age of the older age. After each Minor GC, the age of each object increases by 1, and when this parameter value is exceeded, the object enters the old age
UseAdaptiveSizePolicy Dynamically adjusts the size of the various regions in the Java heap and the age into the old age
HandlePromotionFailure Whether to allow the allocation guarantee to fail, that is, the remaining space of the old generation is not enough to cope with the extreme case that all objects in the whole Eden and Survivor zone of the new generation survive. After JDK6, this parameter will be invalid
ParallelGCThreads Sets the number of threads to recycle in parallel GC
GCTimeRatio The ratio of GC time to total time. The default value is 99, which allows 1% of GC time. Only valid when using the Parallel Scavenge collector
MaxGCPauseMillis Set the maximum pause time for GC. Only valid when using the Parallel Scavenge collector
CMSInitiatingOccupancyFraction Sets the CMS collector to trigger garbage collection after the old time has been used. The default value is 68% and only takes effect when the CMS collector is used
UseCMSCompactAtFullCollection Sets whether the CMS collector should perform a memory defragmentation after garbage collection is complete. Only valid when using the CMS collector
CMSFullGCsBeforeCompaction Setting the CMS collector to start memory defragmentation after several garbage collections only takes effect when the CMS collector is in use
-XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m Set the initial size and maximum size of the meta-space
-Xmx20m -Xms10m Maximum heap space, initial heap space
-XX:MaxDirectMemorySize=10M Maximum direct memory space
-XX:+PrintGC Outputting GC Logs
-XX:+PrintGCDetails Prints verbose logs for GC
-XX:+PrintGCTimeStamps The timestamp of the output GC (in the form of base time) is the time since JVM startup
-XX:+PrintGCDateStamps The output GC timestamp (in the form of a date, for example, 2013-05-04T21:53:59.234+0800) is the initial GC execution time
-Xss128k The stack depth
-Xmn Cenozoic size
-XX:+/-UseTLAB Set whether the JVM uses TLAB
-XX:+printFlagsFinal View the parameter defaults
-XX:+HeapDumpOnOutOfMemoryError OOM generate dump
-XX:+HeapDumpOnCtrlBreak Hold CTRL + break to generate dump
-XX:MaxDirectMemorySize Direct memory size
-XX:+DisableExpicitGC Disallow manual system.gc ()
-XX:+AlwaysTenure Indicates that there are no surviving zones and all objects will be promoted to the old age on the first GC
-XX:+PrintGCApplicationStoppedTime Prints the time the program is paused during garbage collection. Can be mixed with the above
-Xloggc:gc.log Output gCLOg in the same directory
-XX:+PrintReferenceGC It is used to trace soft references, weak references, and virtual references in the system, and display the reference process

Memory allocation and reclamation policies

Automatic memory management in Java ultimately boils down to two things: automatically allocating memory to objects and reclaiming memory from objects

Object allocation

Memory allocation for objects, in general, is heap allocation, mainly in the Eden region of the new generation. If local thread caching is enabled, it will be allocated on the TLAB first, or in rare cases directly to the old generation, depending on which collector is used and which JVM parameters are set

TLAB (Thread local allocation Buffer (-xx :+/ -usetlab) specifies that each thread preallocates a small chunk of memory in the Java heap. If the thread needs to allocate memory, it allocates it on the TLAB of the thread. If the TLAB is used up and a new TLAB is allocated, the synchronization lock is required

In most cases, objects are allocated in Eden of the new generation. When Eden does not have enough space to allocate, the virtual machine will initiate a Minor GC

MinorGC, or YoungGC, happens in the new generation of GC because most Java objects live and die. So MinorGC is very frequent and generally very fast

FullGC occurs in old GC and is usually accompanied by at least one MinorGC, which is generally more than 10 times slower than MinorGC

package com.practice.JVM.ObjectAllocation;

/ * * *@author zhaoxu
 * @version 1.0
 * @className EdenToOld
 * @descriptionThere is not enough space in Eden, so it is guaranteed by the old age@date 2019/12/11 15:59
 * vm args -XX:+UseSerialGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCDateStamps  -XX:+PrintGCTimeStamps -Xms20m -Xmx20m -Xmn10m -XX:SurvivorRatio=8
 **/
public class EdenToOld {
    private static final int _1MB = 1024*1024;

    public static void main(String[] args) {
       // Maintain 1 Byte array containing 1024*1024 Byte elements, of course 1MB
// Byte[] allocation1 = new Byte[2 * _1MB];
// Byte[] allocation2 = new Byte[4 * _1MB];
// Byte[] allocation3 = new Byte[6 * _1MB];

        Byte[] allocation1 = new Byte[2 * _1MB];
        Byte[] allocation2 = new Byte[2 * _1MB];
       Byte[] allocation3 = new Byte[2 * _1MB];
       Byte[] allocation4 = new Byte[4 * _1MB];

    }
}

print
2019-12-11T16:33:39.897+0800: 0.170: [GC (Allocation Failure) 2019-12-11T16:33:39.897+0800: 0.170: [DefNew: 5188K->1024K(9216K), 0.0015865 secs]2019-12-11T16:33:39.898+0800: 0.171: [Tenured: 8357K->9380K(10240K), 0.0043435 secs] 13380K->9380K(19456K), [Metaspace: 3195K->3195K(1056768K)], 0.0059865 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] 
2019-12-11T16:33:39.903+0800: 0.176: [Full GC (Allocation Failure)The 2019-12-11 T16:33:39. 903 + 0800:0.176: [Tenured: 9380 k - > 9332K(10240K), 0.0037593 secs] 9380 - > 9332 kK(19456K), [Metaspace: 3195K->3195K(1056768K)], 0.0037828 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at com.practice.JVM.ObjectAllocation.EdenToOld.main(EdenToOld.java:21)
Heap
 def new generation   total 9216K, used 330K [0x00000000fec00000.0x00000000ff600000.0x00000000ff600000)
  eden space 8192K,   4% used [0x00000000fec00000.0x00000000fec52ac0.0x00000000ff400000)
  from space 1024K,   0% used [0x00000000ff500000.0x00000000ff500000.0x00000000ff600000)
  to   space 1024K,   0% used [0x00000000ff400000.0x00000000ff400000.0x00000000ff500000)
 tenured generation   total 10240K, used 9332K [0x00000000ff600000.0x0000000100000000.0x0000000100000000)
   the space 10240K,  91% used [0x00000000ff600000.0x00000000fff1d2c0.0x00000000fff1d400.0x0000000100000000)
 Metaspace       used 3285K, capacity 4496K, committed 4864K, reserved 1056768K
  class space    used 353K.capacity 388K.committed 512K.reserved 1048576K

Process finished with exit code 1

Copy the code

The result of the program is completely different from the book, I use Serial collector, I do not know what is taking up a lot of memory space

Big object goes straight to the old age

Large object refers to Java objects that need a lot of consecutive memory space, the most typical is the kind of a long string and array use – XX: PretenureSizeThreshold = 111 b, to make large objects helicopters and old age Note: this parameter applies only to Serial and ParNew, PS don’t know

Long-term survival into the old age

The virtual machine defines an Age counter for each object. When the object is born in Eden and passes a minorGC, the Age is +1 for each minorGC passed by Survivor. The default parameter -xx :MaxTenuringThreshold=15. An object in Survivor with an age of 1 enters the old age in the next GC

Dynamic object age determination

To better adapt to different situations, virtual machines do not always require that the age of objects must reach MaxTenuringThreshold. If the total size of all objects of the same age in a Survivor space is greater than half of that in a Survivor space, objects older than or equal to this age can directly enter the old age

For example, if the total size of Survivor area is 1024KB, two 300KB objects with ages of 2 can be copied to the old Age. If only one of them is 2, it will not be copied to the old Age

Space allocation guarantee

Before MinorGC occurs, the JVM checks to see if the maximum available continuous space of the old age is greater than the total space of all objects of the new generation. If this condition is true, the MinorGC is safe even in extreme cases (all objects of the new generation survive)

If this is not true, the JVM looks at the HandlePromotionFailure setting to see if the guarantee is allowed to fail. If this is allowed, the JVM continues to check if the maximum contiguity available in the old age is greater than the average size of objects promoted to the old age over time If it is, try a minorGC, even though the GC is risky. If it succeeds, it succeeds, and if it fails, a FullGC is launched after the failure

If less than, or risk is not allowed, then change to FullGC once

Although the circle of guarantee failures is the largest, guarantee failures are allowed in most cases to avoid too frequent FullGC

After JDK6, this parameter is invalid

The current rule is that MinorGC will be performed as long as the old continuous space is greater than the total size of the new generation object or the average total size of the previous promotions, otherwise FullGC will be performed.