In this article, we will talk about garbage collection (Garbage Collection) in java.
memory in JVM is divided into three parts:
Young Generation (young generation)
As the name suggests, Young Generation is a memory area for new, newly created objects.
When the Young Generation area fills up, a Minor GC is triggered.
With Minor GC, “dead” objects are removed from Young Generation.
The more “dead” objects in the Young Generation, the faster the Minor GC runs.
At Minor GC, a “stop the world” occurs – all threads in the application stop.
Let’s take a closer look at the Young generation structure.
Young generation is divided into three parts: Eden, S0, S1.
When filling Eden space occurs minor GC: all “live” objects are moved to one of the spaces of surviving objects (survivor space): S0 or S1. Suppose, in our case, all objects will be moved to S0.
For further experimentation, I wrote and ran a program that creates short-lived objects.
Let’s see memory allocation in Visual GC (plugin for VisualVM).
As you can see, there are very few objects in S0, and as soon as Eden Space is full, all objects that have links are moved to S1.
Old generation (old generation)
Old generation contains long-lived objects.
As a rule, this area is larger than the area for the young generation.
When filling (or reaching a given threshold), a Major GC occurs.
Typically, Major GCs run slower and less frequently than minor GCs.
How can you use this information to optimize memory usage?
It all depends on the type of application.
If you have a lot of temporary objects, then there will be a lot of Minor GC. In this case, you can use the option XX:NewRatio=1to distribute 50% to young generation and 50% to old generation.
Default NewRatio=2, i.e. young generation is 1/3 of the whole heap.
With many long-lived objects, you can make the old generation area larger by increasing NewRatio.
Why are two survivor spaces used?
You must have wondered why two survivor spaces are used? To combat memory fragmentation. Every time you copy objects from eden to survivor, you get an empty eden and one empty survivor.
Garbage collection algorithms
The JVM has several garbage collectors with different algorithms for the young and old generations. There are three types of algorithms.
Serial collector (serial collector)
Used for garbage collection one thread. Suitable for simple applications with uniprocessor machines.
Parallel collector (parallel collector)
Unlike a serial collector, which uses a single thread, a parallel one uses several flows. Effective with sufficient memory and the number of processor cores.
Concurrent collector (competitive collector)
The concurrent collector does garbage collection along with the work of your application’s threads. Effective for applications that process medium to large datasets and require fast response times.
For young and old generations, different, but compatible, GC algorithms can be used. For example, you can’t use Parallel Scavenge for the young generation at the same time as Concurrent Mark Sweep for the old one, because Parallel Scavenge does not provide the synchronization required by the CMS.
After Java 8, there have been many changes in garbage collection, which I will cover in other articles.
We invite everyone to the demo-lesson “Redefinition, hiding, redeclaration”. In the lesson, we will look at overriding and hiding methods in Java, as well as redeclaring and hiding variables; Let’s get acquainted with four rules, and then also with the fifth. Registration available link.