This is from a Java process running with a 24G heap, G1GC, on some open source variant of JDK 11.
[info ][gc,marking ] GC(132605) Concurrent Mark (728435.456s, 728445.080s) 9624.269ms
I've done some googling around to see what this might be, but I never find what this particular message means.
Java garbage collection is the process by which Java programs perform automatic memory management. Java programs compile to bytecode that can be run on a Java Virtual Machine, or JVM for short. When Java programs run on the JVM, objects are created on the heap, which is a portion of memory dedicated to the program.
Java Garbage Collector (GC) logs are used for memory management and object allocation and promotion. GC logs consist of critical information such as the duration of the GC process, the number of objects promoted, and more. It includes details of the entire GC process and the resources it uses.
G1 copies objects from one or more regions of the heap to a single region on the heap, and in the process both compacts and frees up memory. This evacuation is performed in parallel on multi-processors, to decrease pause times and increase throughput.
Incorrect or non-optimized garbage-collection configurations are the most common cause for GC-related performance problems. These are also the easiest to fix, since they do not require any code changes. Memory leaks, as you will see in the next chapter, are a very different story.
G1 GC uses the Snapshot-At-The-Beginning (SATB) algorithm, which takes a snapshot of the set of live objects in the heap at the start of a marking cycle. The set of live objects is composed of the live objects in the snapshot, and the objects allocated since the start of the marking cycle.
Common triggers for garbage collection are Eden space being full, not enough free space to allocate an object, external resources like System. gc(), tools like jmap or not enough free space to create an object.
Yes, its not a pause time.
You can also add safepoint logger to see any additional pauses.
But otherwise I think all actual pauses are logged in clear way, stating what part is a pause. For example Pause Young (Mixed) (G1 Evacuation Pause)
It should be GC(number of GC) Concurrent Mark(clock start time, clock end time) time
Where click time is relative time from aplication launch. And time at the end is just how long it took, also real wall time.
You can verify this stright in the source: https://github.com/openjdk/jdk/blob/7ccf4358256a0fef895e4081f90b04f71d21bf9d/src/hotspot/share/gc/g1/g1ConcurrentMarkThread.cpp#L184-L220
log_info(gc, marking)("Concurrent Mark (%.3fs, %.3fs) %.3fms",
TimeHelper::counter_to_seconds(mark_start),
TimeHelper::counter_to_seconds(mark_end),
TimeHelper::counter_to_millis(mark_end - mark_start));
If you have enough of logging enabled you should see a line:[info ][gc,marking ] GC(132605) Concurrent Mark 728435.456s
or[728435.456s][info ][gc,marking ] GC(132605) Concurrent Mark 728435.456s
Somehwere above, marking the beginning of concurrent mark. (the time at the beginning here would be uptime decorator to gc logger)
printed by one of first lines in sources above:
log_info(gc, marking)("Concurrent Mark (%.3fs)",
TimeHelper::counter_to_seconds(mark_start));
that is CPU time. In general, the name concurrent is there for a reason. Let's see that via an example:
public class Del {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<>();
while (true) {
map.put(new Random().toString(), new Random().nextInt());
}
}
}
And invoke it via:
java -Xms50M -Xmx50M "-Xlog:heap*=debug" "-Xlog:gc*=debug" Del.java
In my particular run, the relevant to your question logging starts at this line:
....
[0.667s][info ][gc ] GC(11) Concurrent Mark Cycle
....
[0.668s][info ][gc,marking] GC(11) Concurrent Mark From Roots
....
So GC says, OK time to start a "concurrent mark". Notice that is already knows the roots (concurrent marking has to start from somewhere, after all). The root knowledge (where the roots are) was computed in the previous GC cycle.
Then look at where that GC(11)
cycle continues:
[0.739s][info ][gc ] GC(22) Pause Young (Normal) (G1 Evacuation Pause) 43M->42M(50M) 4.566ms
[0.739s][info ][gc,cpu ] GC(22) User=0.01s Sys=0.00s Real=0.00s
[0.739s][debug][gc,ref ] GC(11) Preclean WeakReferences 4.713ms
...
[0.739s][info ][gc,start] GC(11) Pause Remark
Notice that there were other 11
gc cycles (22 -> 11
), while this concurrent one was executing.
I'd like also to point you to this log:
[0.739s][info ][gc,start] GC(11) Pause Remark
This is a remark phase, some attribute this to concurrent phase, which is a STW phase; but notice that G1 track it's time individually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With