简体   繁体   中英

Minor and Major GC cycles

AFAIK, Java GC has minor GC(low cost) and major GC cycles(high cost). If the object is in local scope, it is cleaned in minor GC. If the object's reference is stored somewhere else in the code, that it is cleaned in major GC.
So for example

void f() {
   A a = new A();
   a.doSomething();
}

According to my description(if it is true of course) object a is cleaned in minor GC. What about

void f() {
   A a = new A();
   B b = new B();
   b.doSomething(a);
}

Here object a is passed as a parameter to B's doSomething method and maybe B stores the reference in B's itself but we don't know. In this case, object a will be cleared in minor GC or major GC?

You cannot tell just by looking at the code. GC will run based on demand and the frequency of GCs will vary for each run of the program and environment. The frequency of GC cycles (and the JVM implementation) will then determine whether an object is going to be collected while still in Young generation or it will be promoted to the Old gen. When in the Old gen, an object can still be collected in the "concurrent" phase (depending on the collector) and not necessarily during Full stop-the-world GC.

This may give you a good overview of the whole process: https://www.oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/index.html

Moreover, this is a good article to understand the differences between minor, major and Full GC: https://plumbr.io/blog/garbage-collection/minor-gc-vs-major-gc-vs-full-gc

You need a bit of help on your basic assumptions of how GC works.

We'll assume you're using HotSpot with G1 as there are several other alternatives that work in different ways (like C4 in Zing from Azul, who I work for).

The heap is divided into two regions, called the young and old generation. When objects are first allocated, space is provided from the Eden space, which is part of the young generation (sometimes large objects are allocated directly in the old gen. but let's keep things simple like in your example). Allocation in Eden space uses a simple pointer bumping method, which results in very fast allocation.

When the current allocation pointer reaches the end of the available memory range, a minor GC occurs. This copies objects to a survivor space, between survivor spaces and promotes longer-lived object to the old gen. The allocation pointer is then reset to the beginning of Eden space, effectively collecting all garbage for free.

The old gen. is a separate logical area of memory and uses different algorithms to reclaim space and eliminate fragmentation. This is a major collection.

When these collections occur is not predicated by where an object is allocated but by when the VM decides a collection is necessary. This will be determined by when Eden space is exhausted or when free space in the old gen. falls below a certain threshold.

In your first example, there is no guarantee that the object 'a' will be collected during a minor GC. If doSomething() takes a long time and there are other threads allocating lots of objects, several minor GCs could occur and 'a' could end up being promoted to the old gen. (and collected as part of a major GC).

In the case of your second example, if doSomething() returned quickly and did not record the reference to 'b' anywhere, both 'a' and 'b' could be collected as part of a minor GC.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM