ParNew collector for JAVA Garbage Collector
1, Features
The ParNew collector is a type of Garbage Collector in Java virtual machines. It is a multi-threaded version of the Serial collector. In addition to using multiple threads for garbage collection, other behaviors include all the control parameters available for the Serial collector (for example,-XX: Invalid vorratio,-XX: pretenureSizeThreshold,-XX: HandlePromotionFailure, etc.), collection algorithms, Stop The World, object allocation rules, and collection policies are all consistent with The Serial collector.
2. Status quo
ParNew is the preferred new generation collector for many virtual machines running in Server mode. In JDK1.6 and earlier versions, apart from the Serial collector, ParNew can only work with the CMS collector.
During the JDK 1.5 period, HotSpot launched a kind of epoch-making spam collector (CMS collector, this section will introduce this collector in detail later. This collector is the first real concurrency collector in the HotSpot virtual machine, for the first time, it enables the garbage collection thread to work with the user thread (basically) at the same time. In the previous example, that is, when your mom cleans the room, you can also throw paper scraps to the ground.
Therefore, when using CMS in JDK 1.5 to collect data from the old generation, the new generation can only select one of the ParNew or Serial collectors. The ParNew collector is also the default New Generation collector after the-XX: + UseConcMarkSweepGC option is used. You can also use the-XX: + UseParNewGC option to forcibly specify it.
3. Fixed Java Virtual Machine Space
Source code:
Package com. gc;
Import java. util. ArrayList;
Import java. util. List;
/**
* Simple memory recovery for Java virtual machines and use of the parNew collector
* For running parameters, see the specific method.
* @ Author fan fangming
*/
Public class EasyParNew {
Public byte [] placeHolder = new byte [64*1024]; // placeHolder
Public static void main (String [] args) throws Exception {
OutOfMemoryByFixSize ();
}
/**
* Fixed the size of the Java VM.
* Parameter:-Xms30m-Xmx30m-Xmn10m-XX: + UseParNewGC-XX: + PrintGCDetails
* @ Author fan fangming
*/
Private static voidoutOfMemoryByFixSize () throws Exception {
List <EasyParNew> list = new ArrayList <EasyParNew> ();
While (true ){
EasyParNewserial = new EasyParNew ();
List. add (serial );
Thread. sleep (10); // pause for 10 ms
}
}
/**
* The size of the Java Virtual Machine can be expanded as appropriate, including Xms30m and Xmx40m.
* Parameter:-Xms30m-Xmx40m-XX: + UseParNewGC-XX: + PrintGCDetails
* @ Author fan fangming
*/
Private static voidoutOfMemoryByExpansionSize () throws Exception {
List <EasyParNew> list = new ArrayList <EasyParNew> ();
While (true ){
EasyParNewserial = new EasyParNew ();
List. add (serial );
Thread. sleep (10); // pause for 10 ms
}
}
}
Parameters:
-Xms30m-Xmx30m-Xmn10m-XX: + UseParNewGC-XX: + PrintGCDetails
-XX: + UseParNewGC indicates that the parNew collector must be forcibly used to recycle space in the new generation.
Running result:
[GC [ParNew: 8137 K-> 980 K (9216 K), 0.0057214 secs] 8137 K-> 8022 K (29696 K), 0.0057563 secs] [Times: user = 0.01sys = 0.00, real = 0.01 secs]
[GC [ParNew: 9131 K-> 1021 K (9216 K), 0.0058799 secs] 16173 K-> 16215 K (29696 K), 0.0059148 secs] [Times: user = 0.00sys = 0.00, real = 0.01 secs]
[GC [ParNew: 9207 K-> 9207 K (9216 K), 0.0000123 secs] [Tenured: 15194 K-> 20447 K (20480 K ), 0.0071258 secs] 24401 K-> 24289 K (29696 K), [Perm: 2086 K-> 2086 K (12288 K)], 0.0071911 secs] [Times: user = 0.00 sys = 0.00, real = 0.01 secs]
[Full GC [Tenured: 20447 K-> 20447 K (20480 K), 0.0038141 secs] 29576 K-> 29543 K (29696 K), [Perm: 2086 K-> 2086 K (12288 K)], 0.0038490 secs] [Times: user = 0.00 sys = 0.00, real = 0.00 secs]
[Full GC [Tenured: 20447 K-> 20436 K (20480 K), 0.0063466 secs] 29543 K-> 29532 K (29696 K), [Perm: 2086 K-> 2084 K (12288 K)], 0.0063865 secs] [Times: user = 0.00 sys = 0.00, real = 0.01 secs]
Exception in thread "main" java. lang. OutOfMemoryError: Java heap space
Atcom. gc. EasyParNew. <init> (EasyParNew. java: 12)
Atcom. gc. EasyParNew. outOfMemoryByFixSize (EasyParNew. java: 25)
Atcom. gc. EasyParNew. main (EasyParNew. java: 14)
Heap
Par new generation total 9216 K, used 9152 K [0x03c10000, 0x04610000, 0x04610000)
Eden space 8192 K, 100% used [0x03c10000, 0x04410000, 0x04410000)
From space 1024 K, 93% used [0x04410000, 0x045000f0, 0x04510000)
To space 1024 K, 0% used [0x04510000, 0x04510000, 0x04610000)
Tenured generation total 20480 K, used 20436 K [0x04610000, 0x05a10000, 0x05a10000)
The space 20480 K, 99% used [0x04610000, 0x05a052b8, 0x05a05400, 0x05a10000)
4. scalable Java Virtual Machine Space
Use the outOfMemoryByExpansionSize method and related parameters in the source code.
The running result is as follows:
[GC [ParNew: 1990 K-> 132 K (2112 K), 0.0007742 secs] 24112 K-> 24110 K (30528 K), 0.0007964 secs] [Times: user = 0.00sys = 0.00, real = 0.00 secs]
[GC [ParNew: 1990 K-> 130 K (2112 K), 0.0008112 secs] 25969 K-> 25965 K (30528 K), 0.0008477 secs] [Times: user = 0.00sys = 0.00, real = 0.00 secs]
[GC [ParNew: 1988 K-> 130 K (2112 K), 0.0009319 secs] 27823 K-> 27821 K (30528 K), 0.0009553 secs] [Times: user = 0.00sys = 0.00, real = 0.00 secs]
[GC [ParNew: 1991 K-> 134 K (2112 K), 0.0008219 secs] [Tenured: 29548 K-> 29551 K (29568 K ), 0.0031503 secs] 29682 K-> 29679 K (31680 K), [Perm: 2086 K-> 2086 K (12288 K)], 0.0040531 secs] [Times: user = 0.01 sys = 0.00, real = 0.00 secs]
[GC [ParNew: 2562 K-> 194 K (2880 K), 0.0024877 secs] 32113 K-> 32113 K (40704 K), 0.0025124 secs] [Times: user = 0.00sys = 0.00, real = 0.00 secs]
[GC [ParNew: 2756 K-> 196 K (2880 K), 0.0010854 secs] 34676 K-> 34680 K (40704 K), 0.0011096 secs] [Times: user = 0.00sys = 0.00, real = 0.00 secs]
[GC [ParNew: 2758 K-> 196 K (2880 K), 0.0011059 secs] 37243 K-> 37241 K (40704 K), 0.0011285 secs] [Times: user = 0.03sys = 0.00, real = 0.00 secs]
[GC [ParNew: 2758 K-> 2758 K (2880 K), 0.0000123 secs] [Tenured: 37045 K-> 37813 K (37824 K ), 0.0037394 secs] 39803 K-> 39798 K (40704 K), [Perm: 2086 K-> 2086 K (12288 K)], 0.0037977 secs] [Times: user = 0.00 sys = 0.00, real = 0.00 secs]
[Full GC [Tenured: 37813 K-> 37813 K (37824 K), 0.0034278 secs] 40569 K-> 40567 K (40704 K), [Perm: 2086 K-> 2086 K (12288 K)], 0.0034685 secs] [Times: user = 0.00 sys = 0.00, real = 0.00 secs]
[Full GC [Tenured: 37813 K-> 37792 K (37824 K), 0.0107084 secs] 40567 K-> 40546 K (40704 K), [Perm: 2086 K-> 2084 K (12288 K)], 0.0107696 secs] [Times: user = 0.01 sys = 0.00, real = 0.01 secs]
Exception in thread "main" java. lang. OutOfMemoryError: Java heap space
Atcom. gc. EasyParNew. <init> (EasyParNew. java: 12)
Atcom. gc. EasyParNew. outOfMemoryByExpansionSize (EasyParNew. java: 39)
Atcom. gc. EasyParNew. main (EasyParNew. java: 14)
Heap
Par new generation total 2880 K, used 2810 K [0x03bf0000, 0x03f00000, 0x03f00000)
Eden space 2624 K, 99% used [0x03bf0000, 0x03e7e8e8, 0x03e80000)
From space 256 K, 75% used [0x03ec0000, 0x03ef0030, 0x03f00000)
To space 256 K, 0% used [0x03e80000, 0x03e80000, 0x03ec0000)
Tenured generation total 37824 K, used 37792 K [0x03f00000, 0x063f0000, 0x063f0000)
The space 37824 K, 99% used [0x03f00000, 0x063e82e0, 0x063e8400, 0x063f0000)
Compacting perm gen total 12288 K, used 2105 K [0x063f0000, 0x06ff0000, 0x0a3f0000)
The space 12288 K, 17% used [0x063f0000, 0x065fe4a8, 0x065fe600, 0x06ff0000)
5. Differences between the ParNew collector and the Serial collector
The ParNew collector has no better effect than the Serial collector in a single CPU environment, even because of the thread interaction overhead, this collector cannot completely surpass the Serial collector in two CPU environments implemented through hyper-Threading Technology. Of course, as the number of CPUs that can be used increases, it is very beneficial for the utilization of system resources during GC. The number of collection threads enabled by default is the same as the number of cpus. There are a lot of CPUs (for example, 32, the CPU is usually 4 cores and hyper-threading, more and more servers with more than 32 logical CPUs) in the environment, you can use the-XX: ParallelGCThreads parameter to limit the number of garbage collection threads.
Parallel: Multiple garbage collection threads work in Parallel, but the user thread is still waiting.
Concurrent: indicates that the user thread and the garbage collection thread are executed simultaneously (but not necessarily in parallel, and may be executed alternately), and the user program continues to run, the garbage collection program runs on another CPU.
[GC [DefNew: 1986 K-> 128 K (2112 K), 0.0011191 secs] 27809 K-> 27808 K (30528 K), 0.0011425 secs] [Times: user = 0.00 sys = 0.01, real = 0.00 secs]
And
[GC [ParNew: 1990 K-> 132 K (2112 K), 0.0007742 secs] 24112 K-> 24110 K (30528 K), 0.0007964 secs] [Times: user = 0.00 sys = 0.00, real = 0.00 secs]
The GC [ParNew indicates that the parNew collector is used.
GC [DefNew indicates that the serial collector is used.