编程知识 cdmana.com

Garbage collectors in the new JDK: Shenandoah, ZGC and improved G1

ZGCShenandoah and G1 Improvements in bring developers closer to no pause time than ever before .

In the past six months , Some of the most exciting developments are JDK Garbage collector (GC) Continuous development , First , We will introduce Shenandoah, It's a low latency GC, Mainly run at the same time as the application ; We will also introduce as jdk12 Part of the ZGC(java11 Introducing concurrency GC Low delay at ) The latest improvements ; We will explain in detail Java9 Start As G1 Default GC Two improvements of .

Shenandoah

Shenandoah As a new GC Of JDK 12 part . actually ,Shenandoah Our development work has also been transplanted back to JDK8U and 11u Version improvements .

Shenandoah The team has focused on SpecJBB On the benchmark of , Released a benchmark score for pause delay , The benchmark will delay with JDK 9 stay G1 The times made a comparison . It turned out to be a great progress .

Shenandoah stay G1 The main progress above is to complete more garbage collection cycles when running application threads .G1 Only when the application is paused ( move objects ) Empty the heap area when ,Shenandoah You can relocate objects while the application is running .

To achieve concurrent relocation , It uses what's called Brooks The pointer . Pointer is Shenandoah Each object in the heap has an additional field , It points to the object itself .Shenandoah This is because , When it moves an object , It also needs to fix all objects in the heap that reference the object . When Shenandoah When moving an object to a new location , The pointer will remain in its original position , This forwards the reference to the new location of the object . When referencing an object , The application will follow the forward pointer to the new location . Last , Need to clear old objects with forward pointers , But by separating the cleanup operation from the step of moving the object itself ,Shenandoah Easier to reposition objects at the same time .

Start using Shenandoah To Java 12, Please enable it with the following options :

-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC

If you cannot upgrade to Java12, But you're not interested in trying Shenandoah Interested in , Then you can use Java8 and Java11 Reverse porting of . It is worth noting that ,Oracle Additional JDK Not building Shenandoah Enable , But other things enabled by the publisher OpenJDK... By default ,Shenandoah.

At the same time GC aspect ,Shenandoah Not the only choice .ZGC yes OpenJDK, It comes with another GC( Include Oracle structure ), And already in JDK 12 Has been improved . therefore , If your application encounters a garbage collection pause , And you're thinking about trying Shenandoah, Then we should also pay attention to ZGC, We will discuss it below .

Uninstall using concurrent classes ZGC

Our main goal is low latency 、 Scalability and ease of use . therefore ,ZGC allow Java The application continues to run , Perform all other garbage collection operations except thread stack scanning at the same time . It can come from hundreds of MB Extended to TB The size of Java Pile up , meanwhile , Always maintain a very low pause time ( Usually in 2 Within milliseconds ).

For application developers and system architects , Unexpected low pause times can have far-reaching effects . Developers will no longer need to worry about designing complex methods to avoid garbage collection pauses . and , System architects don't need professional GC Performance tuning expertise to achieve ​​ Low reliable pause time , This is very important for many use cases . This makes ZGC Ideal for large memory requirements ( for example , big data ) Applications for . however , For smaller heaps that require predictable and very short pause times ,ZGC It's also a good choice .

ZGC Has been added to JDK 11 As an experimental function . keep JDK 12 unchanged ,ZGC Added support for concurrent class unloading , In order to allow Java The application continues to run during the unloading of unused classes , Instead of suspending execution .

Performing concurrent class unloading is very complex , therefore , Traditionally , Class unloading is done throughout JVM Done in — It's done in a pause when the world stops . First , Determine the set of classes that are no longer in use , First , Reference processing needs to be performed . Then the terminator handles —— This is what we call system implementation Object.finalize() It means . As part of reference processing , You must traverse the set of objects that the finalizer can access , Because finalizers can pass classes through an infinite chain of links , To keep the class active . Unfortunately , It may take a long time to access all the objects that the finalizer can access . In the worst case , You can access the entire Java pill up.ZGC, also Java Applications can run reference processing at the same time ( because ZGC Introduced in JDK 11).

After reference processing ,ZGC Know which classes no longer need . The next step is to clean up all data structures that contain stale and invalid data due to the death of these classes . Clear links from active data structures to invalid or invalid data structures . So , The data structure used for unlinking includes several internal structures JVM data structure , for example , Code cache ( Contains all the JIT Compiled code )、 Class loader data graph 、 String table 、 The symbol table 、 The configuration file 、 Data etc. . After disconnecting the invalid data structure , Invalid data structures will be traversed again to delete them , In order to eventually reclaim memory .

up to now , all JDK GC It is done by stopping the operation , This leads to Java The application has latency issues . For low latency GC, There is a problem . therefore ,ZGC Now use Java, The application runs all these functions at the same time , therefore , No delay loss due to support class unloading . actually , The mechanism of performing concurrent class unloading is introduced to further improve the latency .

ZGC At present, it can be used as an experiment GC, be used for Linux/x86 64 Bit platform , from Java13 Start , Can be in Linux/Aarch Find and use . You can enable it with the following command line options :

-XX:+UnlockExperimentalVMOptions -XX:+UseZGC

G1 improvement

G1 Some improvements have also been made .G1 The collector divides its garbage collection cycle into different pause times .

After assigning objects , first , Objects are regarded as a generation of “ young ” part . When they survive multiple garbage collection cycles , They will eventually “ Retain ”, And then it's seen as “ Already used ”.G1 Different areas in the map contain only one generation of objects , So it can be called the young area or the old area .

In order to make G1 Reach the pause time goal , It needs to be able to determine what can be done within the pause time goal , And complete the work before the end of the suspension period .G1 There is a complex heuristic algorithm to determine the correct workload , These heuristic algorithms are good at predicting the required working time , But they're not always accurate .G1 You can't just collect some young areas , This complicates the situation . It collects all young areas through garbage collection passes .

keep Java12 state , By adding abort G1 Collect pauses to improve this situation .G1 Track the accuracy of its heuristic algorithm , To predict the number of areas to collect , And stop garbage collection only when needed . By placing collection sets ( The set of areas that will be garbage collected in one cycle ), They are divided into two groups : Mandatory and optional areas .

The mandatory area is always GC collect ... In circulation . Collect optional areas as time permits , If you time out without collecting optional areas , The collection channel will stop . Mandatory areas are younger areas , There may also be some older areas . Add old areas to this collection based on two criteria . Add some to make sure you can continue emptying the object , And add some to exhaust the expected pause time .

Heuristics can be calculated by dividing the number of regions in the set candidate by -XX:G1MixedAccountTarget To calculate the number of areas to add . If G1 It is predicted that there will be more time to collect more old areas , It will also add more zones to the mandatory zone set , Until the available pause time is expected to run out 80%.

The result of this work means that you can stop or end mixing GC loop . This will result in lower GC Pause waiting time , also G1 It is likely to reach its pause time goal more frequently .

Quickly return unused memory

Yes ,Java One of the most common criticisms is that it is a memory consumption , Not now .

occasionally , choice ...JVM Allocated more memory than it needs from the command line . If no memory related command line options are provided , that JVM More memory may have been allocated than needed . Allocate unused RAM It's a waste , Especially in the cloud , All resources are measured and correctly calculated . however , What can be done to solve this situation , And it can be improved in terms of resource consumption

A common situation is , The workload that must be handled changes over time : Sometimes more memory is needed , Sometimes less memory is needed . actually , This is usually irrelevant , because JVM A lot of memory is often allocated at startup , Greedily keep it even when you don't need it . In an ideal situation , Unused memory can be removed from JVM Access back to the operating system , So that other applications or containers can use it .

from Java12 Start , Now you can return unused memory .

G1 It has the function of releasing unused memory , But it can only be released during the completion of garbage collection . There are usually few complete garbage collection channels , And I don't want it to happen , Because they cause the application to pause for a long time . take JDK 12 Remain G1 in , Get the function of freeing unused memory during concurrent garbage collection . This feature is particularly useful for most empty heaps . When the heap is almost empty ,GC The loop may take some time to get the memory and return it to the operating system . To ensure that memory is quickly returned to the operating system , from Java 12 Start , If no garbage collection cycle occurs within the time period specified on the command line ,G1 Will attempt to trigger a concurrent garbage collection cycle .G1PeriodicGCInterval Parameters . then , Concurrent garbage collection cycles free memory to the operating system at the end of the cycle .

To ensure that these regular concurrent garbage collection processes do not add unnecessary CPU expenses , They only run when the system is partially idle . The measure used to trigger whether a concurrent cycle is running is the average one minute system load , The value must be lower than the specified value G1PeriodicGCSystemLoadThreshold.

版权声明
本文为[Old K's Java blog]所创,转载请带上原文链接,感谢
https://cdmana.com/2021/10/20211002145756184f.html

Scroll to Top