This document will help you understand how the Real-Time Garbage Collector (RTGC) works, focusing on the most important configuration parameters and use cases. Readme File: Links to all the Java RTS technical documents ContentsIntroduction IntroductionSun Java Real-Time System 2.1 (Java RTS) supports two garbage collectors:
The other garbage collectors featured in the Java SE version of the HotSpot virtual machine are not supported. The default garbage collector is the new real-time garbage collector. This RTGC can be configured to execute in a deterministic manner. The RTGC might exhibit lower throughput than non-real-time collectors, particularly on uniprocessors. For applications that are more sensitive to the collector's throughput than to the pause times caused by the collector's execution, the RTGC can be turned off with the -XX:-UseRTGC option. In this case, the non-real-time, serial collector is used, and all threads except NoHeapRealtimeThreads might suffer from pause times caused by garbage collection. See also the Practical Introduction to Achieving Determinism document for a detailed description of example programs that allow you to begin using Java RTS, including the RTGC, quickly and easily. The RTGC's activity can be configured with a set of special parameters. To guarantee determinism, some minimum configuration is necessary. Further tuning can be performed by trying different values of various parameters, in various combinations. The parameters that you might configure depend upon your level of expertise with the RTGC: basic, advanced, or expert. All the parameters are listed in the tables at the end of this document, in the section Command-Line Options. Real-Time Garbage Collection PrinciplesAny real-time garbage collector is expected to recycle memory without disrupting the temporal determinism of time-critical tasks. In addition, a real-time GC must recycle memory fast enough so that these tasks are not blocked if the memory is exhausted when they attempt to allocate more. This means that a real-time GC must be granted enough processor cycles to complete its work on time. On the other hand, granting it too many processor cycles reduces the application's overall throughput. Therefore, if application throughput is a concern, users must properly configure real-time GCs. Work-based real-time collectors execute when allocations are performed, regardless of the priority of the threads that are executing. Their configuration defines how much time is granted to the GC for each allocation. Time-based real-time collectors execute at specified times, and at top priority. Their configuration defines when and how often the GC should run. For instance these real-time GCs can be scheduled as periodic threads. However, most of the available real-time GCs do not allow threads to preempt the GC. The real-time application could be frozen for a considerable amount of time. The better the real-time GC, the smaller this time can get. Unfortunately, this approach does not scale well on multiprocessors. Another frequent drawback of real-time GCs is that, to ensure determinism, users must analyze the memory behavior of all the threads of their applications. Adding a new low-priority thread that allocates a lot of memory might force the user to change all the configuration parameters of the real-time GC. It might even result in an application for which the GC cannot ensure determinism, requiring the addition of more memory or CPU resources. For instance, this prevents the use of these real-time GCs for a server on which servlets are dynamically added and removed, unless the server has enough memory and CPUs. Sun's Java RTS and its Real-Time Garbage Collector (RTGC) avoid these two pitfalls. Sun's Real-Time Garbage CollectorThe important point about the RTGC provided with Java RTS is that it is fully concurrent, and thus can be preempted at any time. There is no need to run the RTGC at the highest priority, and there is no stop-the-world phase where all the application's threads are suspended during the RTGC execution. On a multiprocessor, one CPU can be doing some GC work while an application thread is making some progress on another CPU. Thus, the RTGC offered by Java RTS is very flexible. While other real-time GCs usually either have to be executed as incremental, periodic, high-priority activities or else induce an allocation-time overhead, the Java RTS RTGC can execute according to many different scheduling policies. In addition, instead of trying to ensure determinism for all the threads of the application, the RTGC considers that the criticality of an application's threads is based on their priority and ensures hard real-time behavior only for real-time threads at the critical level, while trying to offer soft real-time behavior for real-time threads below the critical level. This reduces the total overhead of the RTGC and ensures that the determinism is not impacted by the addition of new low-priority application threads. In addition, this makes the configuration easier because there is no need to study the allocation behavior of an application in its entirety in order to configure the RTGC. Determinism is designed by looking only at the critical tasks. Finally, the RTGC does not use heap generations, and therefore each RTGC run recycles the entire heap. By setting only two parameters, namely a memory threshold and a priority, you can ensure that threads running at critical priority will not be disrupted by garbage collection pauses. The big advantage of this approach is that these parameters are independent of the non-critical part of the application. You do not need to reconfigure the RTGC when you add a new non-critical component or when the machine load changes. The RTGC tries to recycle memory fast enough for the non-critical real-time threads, but without offering any guarantees for them. If the non-critical load increases, the RTGC might fail to recycle memory fast enough for all the threads. However, this will not disrupt the critical threads, as long as the memory threshold is correctly set for the application. Only the non-critical real-time threads will be blocked and temporarily suffer from some jitter, due to memory recycling. The RTGC has an auto-tuning mechanism that tries to find the best balance between determinism and throughput. Expert users can configure a few parameters to control this auto-tuning in order to improve this balance. Java RTS Thread Types and Their PrioritiesThe function of the RTGC is based on the criticality of the
application threads. Critical threads are those that must
execute within well-defined time limits so that their response times
are predictable (that is, deterministic), whereas
non-critical threads do not have these constraints. Java
RTS real-time threads can be critical or non-critical, whereas non-real-time
threads ( The RTGC starts running at its normal priority, and its priority can be boosted to a higher level if memory falls below a certain level. (This is explained in the next section.) Both of these priority values are configurable with command-line options. The critical boundary is the priority boundary between critical and non-critical threads. By default, the critical boundary is the same value as the boosted RTGC priority, but this also is configurable. The thread types and their priorities are summarized as follows:
In all cases, it is the programmer's responsibility to set the correct priority to reflect the level of criticality of any thread in the Java RTS application. Note that this is the base priority of the thread. Threads that share locks with more critical threads can be automatically boosted from time to time, via priority inheritance, to a higher priority, and the RTGC will take into consideration the change to this higher priority. The figure below shows the priority levels for the RTGC and for the different thread types. Figure 1 Priority Levels for RTGC and Threads
By default, the "normal" priority of the RTGC is above that of non-real-time threads (JLTs), but at the lowest priority for real-time threads. When the Java RTS VM determines that memory is getting low, the RTGC priority is boosted to a higher level, but still lower than that of the critical threads. Note: The figure also shows the priority level of the NHRT threads, but these threads do not depend on garbage collection activity since they do not allocate memory from the heap. Real-Time Garbage Collection SchedulingThe most important property for the RTGC is the priority at which it runs. Our real-time garbage collector dynamically changes its priority to try to balance throughput and determinism. For the parallel (multi-processor) version of the RTGC, the number of threads supporting RTGC activity is also important. See the section Improving the Determinism by Using Multiprocessors. The RTGC can function in three different modes during a garbage-collection run, based on the remaining free memory available:
The figure below shows how the RTGC is scheduled (with one CPU), based on free memory thresholds. Figure 2 RTGC Scheduling on One CPU
The RTGC starts its next run at its initial (normal) priority
when free memory goes below the startup memory threshold.
This threshold is calculated from a set of parameters (which the expert user can tune).
One of the parameters used in the calculation of this threshold is
The Java RTS VM calculates a boosted memory threshold,
based on another set of parameters (which the expert user can tune).
One of the parameters used in the calculation
of this threshold is Not shown in the figure above is a further implication of the fine tuning of the RTGC. If the boosted RTGC value is equal to the critical boundary value, then only critical threads can preempt the RTGC. However, the critical boundary could be configured to be higher than the boosted RTGC priority. In this case, threads with priority below the critical boundary but higher than the RTGC boosted priority, despite being non-critical threads, could possibly preempt the RTGC. If the free memory falls below the critical reserved bytes threshold
(specified by the RTGCCriticalReservedBytes
parameter), the non-critical threads are blocked on allocation,
waiting for the RTGC to recycle memory. This guarantees that
the critical RT threads, and only the critical RT threads,
will be able to allocate memory from the reserved amount.
This mode is called the deterministic mode,
as it assures determinism for the critical threads.
If the free memory remains
below The figure also shows the priority level of the NHRT threads, but these threads are not involved in garbage collection since they do not allocate memory from the heap. Tuning the RTGCThe principle behind the RTGC is the balance between determinism and throughput. With a finite amount of system resources (CPU time and memory in particular), Java RTS must ensure determinism for the critical threads, while ensuring that the other threads also are able to execute in a timely manner. Therefore, the RTGC must recycle enough memory for the allocation requests, while not consuming all the CPU cycles. This delicate balance is configured with several parameters. Since the RTGC continuously tunes its own operation, only two of these parameters need to concern the basic user:
The remaining parameters should be used in advanced tuning by the advanced or expert user. Note: The default behavior of Java RTS is to allow the RTGC to use all the CPU power, because determinism is our primary goal. However, with a bad configuration or with applications that have a large percentage of reachable objects, the RTGC might run continuously to try to ensure determinism. Therefore, by default Java RTS forces a wait period between two consecutive RTGC runs in order to help prevent the system from being blocked due to continuous garbage collection. The expert user can configure this wait period with the RTGCWaitDuration parameter. All the parameters are listed in the tables at the end of this document in the section Command-Line Options. Normal Mode: Recycling Memory Without Disrupting Any Real-Time ThreadsThe RTGC auto-tunes the parameters that control the "normal" mode of its functionality. Therefore, the basic user does not need to tune these parameters. The advanced user might need to tune the value of the RTGCNormalPriority parameter. Only expert users should attempt to tune the parameters used to determine when the RTGC starts its next run. In the RTSJ, the impact of the GC on real-time threads is implementation-dependent. With Java RTS, the threads running at the highest priorities can completely avoid garbage collection pauses. However, the RTGC must start soon enough to ensure that it completes before memory is exhausted. This works as long as the allocation behavior is relatively stable, because the RTGC must be started soon enough to handle the worst case allocation. In normal mode, the RTGC runs at a lower priority than the real-time threads. Unfortunately, this does not scale well to larger applications. As a general rule, the more real-time threads are running (and allocating memory), the longer an RTGC cycle lasts. The amount of memory allocated during a cycle can quickly increase. To ensure determinism, we must take into account the worst case allocation behavior, which could possibly cause the RTGC to run continuously. And even this might not be sufficient to guarantee that memory would be recycled fast enough. However, real-world applications normally contain a mix of critical and non-critical tasks. For some of the non-critical tasks, timing is important but not critical. You might be willing to miss a few deadlines when there is an allocation burst. The gain is that this allows the RTGC to start much later, improving the global throughput. With Java RTS, we can configure the behavior of the non-critical threads independently from the behavior of critical ones. We consider that the normal behavior for real-time threads is to run at a higher priority than the RTGC, while the JLTs run at a lower priority than the RTGC. The RTGC starts running at RTGCNormalPriority (which defaults to the minimal real-time priority). The startup memory threshold determines when the RTGC starts. The idea is to start it early enough so that it completes its cycle before reaching the boosted memory threshold, which would increase the RTGC priority to its boosted level, creating jitter for the non-critical real-time threads. The auto-tuning mechanism takes into account the allocation performed during the last RTGC cycles to try to start the RTGC just on time, thus maximizing the throughput while avoiding pause times, assuming that the allocation behavior is stable.
Boosted Mode: Boosting the RTGC PriorityWhen the RTGC priority is boosted, non-critical threads can be preempted by RTGC threads, but the RTGC can be preempted by critical threads. Therefore this can cause non-critical threads to pause for a long time, unless in a multiprocessor environment. See the section Improving the Determinism by Using Multiprocessors. You can specify the value of the boosted priority with the RTGCBoostedPriority parameter.
Deterministic Mode: Ensuring Determinism for Time-Critical ThreadsThe real-time threads that run at a priority higher than the critical boundary are called the critical real-time threads. The RTGC must ensure that their worst case pause time is very low (at worst a few hundreds of microseconds). To guarantee this determinism, you must specify the RTGCCriticalReservedBytes
parameter. You can tune the critical boundary with the When the free memory goes
below the limit specified by RTGCCriticalReservedBytes,
Java RTS blocks the non-critical threads from allocating memory
to prevent them from disrupting the critical threads. If the free memory remains below this threashold
after a few RTGC runs, then Note that the critical threads continue running at a priority higher than the RTGC and can preempt it at any time. If RTGCCriticalReservedBytes is too low, a critical thread might block when the memory is full, waiting for the RTGC to free some memory. If RTGCCriticalReservedBytes is too high, the RTGC will run more often, preventing the lower priority threads from running. Hence, this reduces their global throughput. Improving the Determinism by Using MultiprocessorsThe RTGC is fully concurrent, that is, application threads can run concurrently with the RTGC. Therefore, we can improve the determinism of non-critical threads on multiprocessors by specifying how many worker threads the RTGC can use. This is both simpler and safer than depending on parameter tuning alone. The drawback of parameter tuning alone is that when the RTGC parameters are underestimated, all non-time-critical threads might be suspended from time to time. If they are overestimated, the JLTs will be suspended very often. At worst, they will not make any progress because the RTGC could consume all the CPU not used by the real-time threads. You can specify the initial (normal) and boosted number of parallel worker threads for the RTGC with the RTGCNormalWorkers and RTGCBoostedWorkers options, respectively. Thus, when the RTGC runs, there should still be some CPU cycles not used by the RTGC and the critical threads. (It is assumed that critical threads use only a small part of the CPU power.) Hence, non-critical real-time threads should still be able to make some progress. Even JLTs could get some CPU cycles. When the real-time load is low, RTGCNormalWorkers threads executing the RTGC at RTGCNormalPriority will be enough to cope with allocation performed on the remaining processors. However, if the allocation rate increases or if more real-time threads are running, the RTGC at RTGCNormalPriority, even if running continuously, might not recycle memory fast enough. When this happens, the RTGC priority is boosted, and the number of RTGC threads is increased to RTGCBoostedWorkers. On multiprocessors, as on uniprocessors, the VM performs auto-tuning to try to maximize throughput. It will first try to complete the RTGC on time by using RTGCNormalWorkers threads running at RTGCNormalPriority. Expert users can balance determinism and throughput by using the NormalSlideFactor and NormalSafetyMargin parameters. However, an underestimation has a limited impact because, even if the RTGC is boosted to RTGCBoostedPriority, the non-critical threads still get some CPU power. Expert users should focus on the boosted memory threshold,
which defines when the RTGC threads start running at RTGCBoostedPriority.
This is done through BoostedSlideFactor, BoostedSafetyMargin,
and BoostedMinFreeBytes.
(See the section Description of the Auto-Tuning Mechanism.)
The big advantage to this configuration is that
overestimating the threshold (for example, small slide factors and big
safety margins) is not dangerous. Even if this configuration makes the RTGC run
continuously on RTGCBoostedWorkers processors, there will always be a
few processors available for the lower priority threads. The impact
on determinism depends on the ratio between The following example shows a simple configuration to easily achieve determinism
(though without optimizing throughput) by limiting the number of processors the RTGC
can use at any one time and forcing the RTGC to run continuously.
Since the RTGC usually needs about 25% of the CPU
power in order to guarantee determinism, we allow the RTGC to use two processors
(parallel worker threads), assuming an 8-processor system.
We also force garbage collection to run almost continuously by
specifying the -Xms1G -Xmx1G -XX:NormalMinFreeBytes=1G -XX:RTGCNormalWorkers=2 When making estimations, consider the following:
As a summary, this expert tuning is a parameterized way to offer more determinism for the real-time non-critical threads. In addition, it does not block the machine, avoiding the case where the RTGC runs continuously on all the processors, at very high priority. However, there is no free lunch. This automatic gain in determinism can quickly lead to throughput issues. Description of the Auto-Tuning MechanismThis section describes in detail the auto-tuning mechanism that Java RTS uses to determine the optimal conditions to start the RTGC or to boost its priority. These conditions are referred to as the startup memory threshold and the boosted memory threshold, respectively. Expert users might want to try to tune these threshold values, using specific parameters. Note: This same mechanism is used to determine both the startup memory threshold and the boosted memory threshold; the only difference is that the parameter names begin with Normal and Boosted, respectively. Therefore, we drop Normal and Boosted from the parameter names used in the calculations below. The VM does not try to use the worst case allocation behavior to ensure the RTGC will complete on time, because this would run the RTGC too often after the first period of allocation bursts. Hence, the auto-tuning mechanism uses a depreciation mechanism to compute a "sliding value" at the end of each GC cycle. This sliding value is the higher of its depreciated previous value and the memory that was allocated during the current GC cycle. A safety margin is then applied to this sliding value to compute the next memory threshold. The RTGC will start (or be boosted to its higher priority) when the free memory goes below that threshold. The RTGC uses the amount of memory that was allocated previously in order to estimate the next threshold. It is expected that this value will "slide" to a stable amount. (This is why we call it a "sliding value.") The following formulas are used to calculate the startup memory threshold and the boosted memory threshold:
This calculation is performed at the end each RTGC cycle. In the formulas, the variables have the following meanings:
The expert user can
configure The first formula above uses the sliding value calculated during the previous GC cycle. For the initial cycle of the RTGC, the sliding value is zero, as there was no previous GC cycle. With the slide factor applied, the sliding value is still zero. Therefore, the amount of memory allocated during this first cycle becomes the new sliding value. For subsequent GC cycles, the sliding value calculated during the previous GC cycle is depreciated by the slide factor percentage. This result is compared with the amount of memory allocated during the current GC cycle, and the higher of the two becomes the new sliding value, which represents the amount of memory we predict will be allocated during the next cycle. Then, in the second formula above, this new sliding value,
with the safety margin percentage applied, is compared with the
user-estimated free memory threshold ( The slide factor represents the percentage of memory allocated during the previous cycles that will not be considered in the calculation of the prediction of the allocation needs during the next garbage-collection cycle. In other words, this can be considered as the speed with which allocation bursts are forgotten. As an example, let's say that you have set the As mentioned above, the sliding value is initially zero. It also goes back to zero if no allocations are performed during a few GC cycles. Note that, if the sliding value is zero for the calculation of the
memory thresholds (normal or boosted), the RTGC
could start or be boosted too late and cause jitter for the first few cycles (the
time needed for the application to reach a steady state). If you are
concerned with this "initial learning phase," you can specify a
The Significance for Normal ModeDecreasing NormalSafetyMargin or NormalMinFreeBytes improves throughput by starting the RTGC later. Unfortunately, the RTGC might start too late, particularly at application startup or when the allocation rate increases. In this case the RTGC priority would be boosted, allowing the RTGC to preempt the non-critical real-time threads. Increasing NormalSafetyMargin or NormalMinFreeBytes avoids this situation. Note that if NormalSafetyMargin is too big, the RTGC might run continuously, and threads at a priority lower than RTGCNormalPriority might be prevented from running. This might also happen if the real-time threads often have allocation bursts and the NormalSlideFactor is too low. Increasing NormalSlideFactor allows the RTGC to forget more quickly the allocation bursts, improving the throughput but increasing the likelihood of jitter during the next allocation burst. Significance for Boosted ModeFor boosted mode, these tuning options are mainly useful in a multiprocessing enviroment. See the section Improving the Determinism by Using Multiprocessors. Summary of the RTGC SchedulingThe VM auto-tunes the memory thresholds to try to start or boost the RTGC as late as possible (to maximize throughput) while trying not to have to increase its priority or block the non-critical threads (which impacts their determinism). The RTGC can go through three different phases.
Finding the Right Configuration ParametersAs mentioned above, in order to guarantee determinism, you must configure the RTGCCriticalReservedBytes parameter. This is the only parameter that you are required to configure. You might also want to configure the RTGCCriticalBoundary parameter. For the rest, Java RTS includes several auto-tuning mechanisms to try to lighten the configuration burden, as detailed in Description of the Auto-Tuning Mechanism. Java RTS provides a garbage collector API and a few MBeans to gather additional information. See Using MBeans to Monitor and Configure the RTGC. However, the simplest way to figure what is happening is to use the -XX:+PrintGC command-line option (and optionally -Xloggc:<filename> to redirect the output to a file). After each GC cycle, the RTGC prints information that was gathered during the cycle. For more advanced tuning or debugging, the -XX:+RTGCPrintStatistics command-line option provides additional detailed information. See Examples of Printing RTGC Information for sample output from these options. With respect to critical threads, the most important number to look at
in the The With respect to non-critical real-time threads, the most important number is the priority at which the RTGC ends. All the threads below that priority have suffered from jitter during that GC cycle. This is not an error. It comes from the balance between throughput and determinism. Expert users can try to improve the determinism by ensuring that the worst case is taken into account for a longer time (by reducing the slide factors in the auto-tuning mechanism) and/or that the RTGC can cope with quicker changes in the allocation rates (by increasing the safety margins or the minimum threshold). To optimize the throughput, you can try to tune the RTGC so that the minimum free memory is nearly equal to the memory threshold that would have caused the RTGC to enter the next mode. If RTGCBoostedWorkers is set, you should also determine whether the RTGCCriticalReservedBytes boundary was reached by checking the RTGC output; if the boundary was reached, the RTGC prints the number of blocked threads. In addition, if a non-critical thread blocked on allocation, the "worst" non-fragmented memory will be no more than the value of RTGCCriticalReservedBytes. Additional Note on Pause TimesThe RTGC is truly concurrent. The only time it prevents a thread from running is when it has to look at this particular thread's Java stack, where the local variables and operands are stored. Hence, the main potential source of pause time for a given thread is caused by the scanning of its stack. Since a thread is not impacted by the scanning of the other thread stacks, the pause time for a thread is smaller than with non-concurrent GCs. To reduce this pause time even further, threads should execute in compiled mode. See the Java RTS Compilation Guide for further details on how to compile the methods executed by time-critical code. In general, the pause time primarily depends on the stack's depth. Pause times are very small for threads that do not extensively perform recursive method calls. Do not forget that there are a lot of other jitter sources that might look like RTGC pause times. Java RTS provides solutions to avoid them. For instance, the Java RTS Compilation Guide covers the issues related to late class loading and initialization. Remember also that only real-time priorities provide real-time guarantees. For priorities lower than real-time, the threads are scheduled with a time-sharing policy to reduce the risks of starvation in the non real-time part of the application. Hence, a thread at a priority lower than real-time can be preempted at any time to let lower priority threads make some progress. Using MBeans to Monitor and Configure the RTGCJava RTS provides a garbage collector API, useable from the application code, which allows you to dynamically change the RTGC parameters either locally from your Java application or remotely through management beans. For additional information, look in the Javadoc for the FullyConcurrentGarbageCollector class. The MBeans are registered in the realtime.rtgc namespace and can be viewed with, for example, the JConsole tool. We have also extended the LastGCInfo attribute of the garbage collector MBean. To see a description of the attributes and operations of these MBeans, refer to the corresponding Javadocs:
Command-Line OptionsAll these parameters are intended for a production environment. These parameters are also listed in the Java RTS Options document. Note that the RTGC checks the logical consistency of the parameter values
and adjusts them accordingly. For example, if you specify a value for Caution: The "-XX" options are not part of the official Java API and can vary from one release to the other. RTGC Basic Options
RTGC Advanced Options
RTGC Expert Options
RTGC Obsolete OptionsThe following options are obsolete and should not be used. They will be completely removed in a future version of Java RTS.
Examples of Printing RTGC InformationThis section first provides examples of the output from the Command-Line OutputWhen the [GC 2047K->1925K(2048K, non-fragmented: current 122K / min 1K / worst 0K, blocked threads: max 1 / still blocked 0 requesting 0 bytes, dark matter: 75K in 177 blocks smaller than 2048 bytes) <boosted during 62887 microseconds> {CPU load: 1.05 recycling / 0.04 since last GC} , 0.0635765 secs] With the [GC 2047K->1925K(2048K, non-fragmented: current 122K / min 1K / worst 0K, blocked threads: max 1 / still blocked 0 requesting 0 bytes, dark matter: 75K in 177 blocks smaller than 2048 bytes) <boosted during 62887 microseconds> {CPU load: 1.05 recycling / 0.04 since last GC} GC cycle stats: RTGC completed in deterministic mode (3 workers at priority 40) End free bytes: 105152 bytes Min free bytes: 1024 bytes Next boosted threshold: 72960 bytes Next normal threshold: 139840 bytes Allocations during the GC: in deterministic mode: 60896 bytes (worst 60896 bytes, average 60896 bytes) in boosted+deterministic modes: 60896 bytes (worst 60896 bytes, average 60896 bytes) in normal+boosted+deterministic modes: 60896 bytes (worst 60896 bytes, average 60896 bytes) Total CPU cost in nanoseconds: 66093516 Pacing CPU cost: 100667 (0 %) Serial CPU cost: 5858823 (8 %) Parallel worker_0 CPU cost: 10220120 (15 %) Parallel worker_1 CPU cost: 46879782 (70 %) Parallel worker_2 CPU cost: 2175946 (3 %) Bytes allocated by critical threads: in deterministic mode: 0 bytes total for this cycle: 0 bytes grand total: 0 bytes Minimum RTGCCriticalReservedBytes: 0 bytes , 0.0635765 secs] The output is largely self-explanatory. However, note the following points:
Sample Output from a "Bad" ConfigurationThe following test output from [ 63823K->18950K(65536K, non fragmented: current 46585K / min 1050K / worst 0K, blocked threads: max 0 / still blocked 0 requesting 0 bytes, dark matter: 17572K in 16299 blocks smaller than 2048 bytes) <completed without boosting> {CPU load: 2.22 recycling / 0.06 since last GC} GC cycle stats: RTGC completed in normal mode (4 CPUs at priority 15) End free bytes: 47695680 bytes Min free bytes: 17111136 bytes Next boosted threshold: 171960 bytes Next normal threshold: 1676650 bytes Allocations during the GC: in deterministic mode: 0 bytes (worst 243072 bytes, average 126566 bytes) in boosted+deterministic modes: 0 bytes (worst 243072 bytes, average 126566 bytes) in normal+boosted+deterministic modes: 1367904 bytes (worst 1461152 bytes, average 841890 bytes) Total CPU cost: 231007716 nanoseconds Pacing CPU cost: 285081 (0 %) Serial CPU cost: 6322420 (2 %) Parallel worker_0 CPU cost: 89724588 (38 %) Parallel worker_1 CPU cost: 43886333 (18 %) Parallel worker_2 CPU cost: 46492001 (20 %) Parallel worker_3 CPU cost: 44295704 (19 %) Bytes allocated by critical threads: in deterministic mode: 0 bytes total for this cycle: 16128 bytes grand total: 5322592 bytes Minimum RTGCCriticalReservedBytes: 9216 bytes , 0.1054441 secs] The value of the "worst" non-fragmented memory on the first line of the output
shows that at least one thread blocked during allocation.
Since the "grand total" for "Bytes allocated by critical threads" is not zero,
that means that there were, in fact, some critical threads, and therefore,
Sample Output from a Corrected ConfigurationThe following output from [ 62798K->16857K(65536K, non fragmented: current 48678K / min 2068K / worst 1016K, blocked threads: max 0 / still blocked 0 requesting 0 bytes, dark matter: 15426K in 16298 blocks smaller than 2048 bytes) <completed without boosting> {CPU load: 2.24 recycling / 0.06 since last GC} GC cycle stats: RTGC completed in normal mode (4 CPUs at priority 15) End free bytes: 49825664 bytes Min free bytes: 15991968 bytes Next boosted threshold: 1266976 bytes Next normal threshold: 2853616 bytes Allocations during the GC: in deterministic mode: 0 bytes (worst 277600 bytes, average 160552 bytes) in boosted+deterministic modes: 0 bytes (worst 277600 bytes, average 160552 bytes) in normal+boosted+deterministic modes: 1442400 bytes (worst 1450688 bytes, average 889055 bytes) Total CPU cost: 244487405 nanoseconds Pacing CPU cost: 290305 (0 %) Serial CPU cost: 6557720 (2 %) Parallel worker_0 CPU cost: 46866569 (19 %) Parallel worker_1 CPU cost: 93580338 (38 %) Parallel worker_2 CPU cost: 50525021 (20 %) Parallel worker_3 CPU cost: 46592857 (19 %) Bytes allocated by critical threads: in deterministic mode: 0 bytes total for this cycle: 15616 bytes grand total: 4763680 bytes Minimum RTGCCriticalReservedBytes: 17440 bytes , 0.1102827 secs] With |