This is the 14th day of my participation in the August More Text Challenge

YGC


The YGC frequency is ignored for the moment, and the problem mainly focuses on the GC time. In order to solve the problem of YGC time-consuming, it is necessary to figure out the time-consuming nodes of YGC. (As far as I know, YGC problems have not escaped these dimensions)

  • Scan and mark the time of living objects

  • The surviving object is copied to S and promoted to Old

  • Wait for each thread to reach the safe point

  • GC Log Output

  • Operating system Activity (SWAP)

1. Wait for the thread to reach a safe point

Serial, ParNew, Parallel Scanvange, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld, ParallelOld The user thread is not run.

Where and at what point does the JVM STW go? A: Be safe.

Therefore, when GC is run, the program needs to stop at the nearest safe point (method return, loop end, exception thrown, etc.), as mentioned earlier in the safe point log article:If you find that the Spin period is abnormal, then look at our code to see if there are any logical blocks in our code that prevent threads from reaching safe points quickly, such as large loop bodies.

By the way, the role of safe points is not just for GC. The following points can cause programs to enter safe points, which can be described in a separate article

2. Scan and mark live objects

After the program has reached a safe point, the next step is to analyze the reachability of the root object’s token and reference objects.

2.1 Object references in thread stacks

Two concepts need to be introduced here, OopMap_ and _RememberedSet

In order to retrieve root objects, the JVM needs to find references to heap objects from the thread stack, but not all of them are references. If a full stack scan is used, it would be too time-consuming.

Object references are maintained with OopMap, and when a safe point is reached, the OopMap is updated and then traversed. The accessibility analysis is then assisted by the RememberedSet.

It is important to note that, despite the benefit of the extra storage, the overall markup time for live objects is not something to ignore directly.

For example: in the system of a netizen, there are thousands of business threads in the system because of the problem of the call method, so the time consumption of traversing so many OopMap is also very large.

There are also some programs, because the query statements like SELECT do not add restrictions, resulting in a large amount of data loaded into memory, resulting in a long GC time, or even OOM occurrence.

Therefore, focus on the number of object references, both in a thread and the total number of threads.

2.2 Too many Objects Are Stored in the local Cache

We know that if a subject lives for a certain number of years, it will advance to the old age. If a large number of local cache objects are created, YGC will scan the card table to check if they are alive after they are promoted to the old age, thus increasing YGC’s alive object marking time.

Therefore, the local cache solution should be evaluated for completeness or consider off-heap caching to reduce the impact of local caching on the GC.

2.3 System Class Loader Loads Too many objects

If the application has the logic to parse XML, a new classloader is created for each new XStream object. The classloader will use the class’s permission name as the key and value as the real Klass object and store it in SystemDirectionary. As a result, more and more live objects are stored in memory, which can take a long time to mark.

“The XStream instance is thread-safe. That is, once The XStream instance has been created and configured, It may be shared across multiple threads causing serious objects to be serialized/deserialized concurrently “.

XStream is thread-safe. There is no need to re-initialize an XStream object. Declare a static XStream for each deserialized object and reuse it.

2.4JNI & Monitor & Finalizable, etc

I have not encountered specific exception instances for the time being, and I will add them later when I encounter them.

3. Copy the surviving object

This may not be particularly accurate, since GC for machine 1 will not necessarily happen, but I want to use this simple example to illustrate how the Eden range and the size of the new object affect GC copy, and therefore GC time.

Therefore, be good at using JVM monitoring, estimating the size of new and live objects per call, and designing reasonable Eden and survivor zones in combination with the number of concurrent calls.

4. GC log output

GC logging is one of the more overlooked points, but it can have a negative impact on GC time. Because the total time of STW GC, contains the GC log printing time, under normal circumstances, the output of the limited information GC logs for GC time should be negligible effect of the whole, but if you just met when the GC log output system IO load is very good, so may wait for a long time here in the log output.

One solution is to put GC log files on TMPFS (for example, -xloggc :/ TMPFS /gc.log). Because TMPFS has no disk file backup, TMPFS files do not cause disk behavior and therefore cannot be blocked by disk IO.

Reference: the background IO anomalies caused by GC www.pianshen.com/article/592…

Summary: YGC time-consuming problem can be said to be strange, but the change is not part of it, as long as we can master the influence of several key nodes of YGC, starting from the principle of analysis, there should be no big problem ~