what's the difference between ParallelGC and ParallelOldGC?
I have some questions about the GC Algorithm:
First when we use the parameters such UseSerialGC
, UseParallelGC
, UseParallelOldGC
and so on, we specify a GC Algorithm. Each of them all can do GC in all generation, is it right?
For example, if I use java -XX:+UseSerialGC
, all generation will use serial GC as the GC Algorithm.
Se开发者_如何学JAVAcond can I use ParallelGC
in Old Gneneration and use SerialGC
in young generation?
The last as the title what's the difference between ParallelGC
and ParallelOldGC
?
Take a look at the HotSpot VM Options:
-XX:+UseParallelGC = Use parallel garbage collection for scavenges. (Introduced in 1.4.1).
-XX:+UseParallelOldGC = Use parallel garbage collection for the full collections. Enabling this option automatically sets -XX:+UseParallelGC. (Introduced in 5.0 update 6.)
where Scavenges = Young generation GC.
Well, after lots of search and research what I have come to understand is as below,
-XX:+UseParallelGC - This enables GC to use multiple threads in Young generation but for old/tenured generation still Serial Mark and Compact algorithm is used.
-XX:+UseParallelOldGC - This enables GC to use Parallel Mark and Compact algorithm in old/tenured generation.
Let's understand -
The algorithm and the memory arrangement, such as mark and copy, swap spaces, that works in Young generation does not work for Old generation for many reasons
Low mortality - In the Old Generation, the "mortality rate" is significantly lower than the same in the Young Generation. In a Typical Java application most objects die quickly and few live longer. As the objects which survive in young generation and promoted to old generation, it is observed that these objects tend to live a longer life. Which leads to very less mortality rate in old generation compared to young generation.
Significantly size - The Old Generation is significantly larger than the Young Generation. Because the Young Generation quickly clears up, relatively little space is available for the many short-lived objects (small Young Generation). In the Old Generation, objects accumulate over time. Therefore, there must be much more space in an old generation than in the Young Generation (big old generation)
Little allocation - In the Old Generation less allocation happens than in the Young Generation. This is because in the Old Generation objects arise only when the Garbage Collector promotes surviving objects from the Young to the Old Generation. In the Young Generation, on the other hand, all the objects that the application generates with new, i.e the majority of the allocations, occur in the Young Generation.
Taking these differences into account, an algorithm has been chosen for the Young Generation that will finish garbage collection as soon as possible, because it has to be called often because of the high mortality rate [point (1)]. In addition, the algorithm must ensure that the most efficient possible memory allocation [point (3)] is then possible because much is allocated in the Young Generation. The mark-and-copy algorithm on the Young Generation has these properties.
On the other hand, this algorithm does not make sense on the Old Generation. The situation is different: the garbage collector has to take care of many objects in the Old Generation [point (2)] and most of them are still alive; only a small part has become unreachable and can be released [point (1)]. If the garbage collector were to copy all the surviving objects on each garbage collection, just as it does with mark-and-copy, then it would spend a lot of time copying it without gaining much.
Therefore, the mark-and-sweep algorithm is made on the old generation, where nothing is copied, but simply the unreachable objects are released. Since this algorithm leads to the fragmentation of the heap, one has additionally considered a variation of the mark-and-sweep algorithm, in which, following the sweep phase, a compaction is made, by which the fragmentation is reduced. This algorithm is called a mark-and-compact algorithm.
A mark and compact algorithm can be time consuming as it needs to traverse the object graph in following for stages.
- Marking.
- Calculation of new locations.
- Reference adjustments.
- Moving
In the Calculation of new location phase, when ever it gets a free space, tries to find an object which can move to this space(defragmentation). Stores the the pair for use in later phases. This causes the algorithm consume more time.
Though mark and compare solves some issues specific to tenured generation, it has got some serious issue as this is an STW(Stop the world) event, and consumes much time, can seriously impact the application.
Alternative algorithms for the old generation
In order to reduce the break times, alternatives to the serial mark-and-compact algorithm have been considered:
A parallel mark-and-compact algorithm that still latches all application threads, but then handles labeling and subsequent compaction with multiple garbage collector threads. While this is still a stop-the-world approach, the resulting pause is shorter on a multi-core or multi-processor machine than the serial mark-and-compact algorithm. This parallel algorithm on the Old Generation (called "ParallelOld") has been available since Java 5 Update 6 and is selected with the option -XX: + UseParallelOldGC.
A competing mark-and-sweep algorithm that at least partially rivals the application without stopping its threads, and occasionally needs short stop-the-world phases. This concurrent mark-and-sweep algorithm (called "CMS") has been around since Java 1.4.1; it is switched on with the option -XX:+UseConcMarkSweepGC. Importantly, this is just a mark-and-sweep algorithm; Compaction does not take place, leading to the already discussed problem of fragmentation.
So in a nutshell -XX: + UseParallelOldGC is used as an indication to use multiple threads while doing major collection using Mark and Compact algorithm. If this is used instead, minor or young collection are parallel, but major collections are still single threaded.
I hope this answers .
Those are two gc policies applied to different regions of a Java Heap namely New and Old generations. Here's a link that helps to clarify which options imply other ones. It's helpful especially when starting out to understand what you're getting when you specify say ParallelOldGC or ParNewGC. http://www.fasterj.com/articles/oraclecollectors1.shtml
From Oracle Java SE 8 docs:
https://docs.oracle.com/javase/8/docs/technotes/guides/vm/gctuning/collectors.html
The parallel collector (also known as the throughput collector) performs minor collections in parallel, which can significantly reduce garbage collection overhead. It is intended for applications with medium-sized to large-sized data sets that are run on multiprocessor or multithreaded hardware. The parallel collector is selected by default on certain hardware and operating system configurations, or can be explicitly enabled with the option
-XX:+UseParallelGC
.
Parallel compaction is a feature that enables the parallel collector to perform major collections in parallel. Without parallel compaction, major collections are performed using a single thread, which can significantly limit scalability. Parallel compaction is enabled by default if the option
-XX:+UseParallelGC
has been specified. The option to turn it off is-XX:-UseParallelOldGC
.
So if you specify -XX:+UseParallelGC
, By default major collection will also be done using multiple threads. The reverse is also true i.e. if you specify -XX:+UseParallelOldGC
, minor collections will also be done using multiple threads.
精彩评论