Wednesday, October 15, 2014

Excel: How to Adjust the Scale of the Axis in a Scatter Chart

Routinely, we have been using TextPad and Excel to analyze Garbage Collection (GC) events gathered in GC log files.

In this article, we will demonstrate how to use these data to create a Scatter Chart and also adjust the scale of the horizontal axis in the chart as shown below:

Before Scale Change

After Scale Change

The Data

After cleaning the data, we have two columns holding data as shown below:
  • GC time stamp
  • Mixed GC pause time
Using shift key, you can select both A1 and B1 cells as shown below:

Then you can select entire columns by pressing:[1]

Create a Scatter Chart from Spreadsheet Data

A scatter chart has two value axes, showing one set of numerical data along the x-axis and another along the y-axis. It combines these values into single data points and displays them in uneven intervals, or clusters.

To create a scatter chart, you do:[2]
  1. Arrange your data so that the x-values are in the first column of your worksheet, and the y-values are located in adjacent columns.
  2. Select the range of x- and y-values that you want to plot in the chart.
  3. Click Chart on the Insert menu to start the Chart Wizard.
  4. In the Chart type box, select Scatter .
  5. Under Chart sub-type, click the chart sub-type you want to use.

This will create a scatter chart as shown in diagram 1.  But, you can see the scale of X-axis is not appropriate.

Change the Scale of Horizontal Axis

By default, Microsoft Office Excel determines the minimum and maximum scale values of the axis when you create a chart. However, you can customize the scale to better meet your needs.  To customize the scale of horizontal axis, you do:
  1. Change the label/title of the series to "Mixed GC"[4]
  2. In the chart, click the horizontal (value) axis that you want to change.
  3. This displays the Chart Tools, adding the Design, Layout, and Format tabs.
  4. On the Format tab, in the Current Selection group, click the arrow next to the Chart Elements box, and then click Horizontal (Value) Axis.
  5. In the Current Selection group, click Format Selection.
  6. In the Format dialog box, change maximum value of X-axis from 40000.0 to 30000.0.
Voila, you have created a scatter chart of the Mixed GC diagram with a good scale at horizontal axis (see diagram 2 above).

Sunday, October 12, 2014

JDK 8: Is Tuning MaxNewSize in G1 GC a Good Idea?

For a throughput GC such as Parallel GC, it often helps performance by setting MaxNewSize (or -Xmn).  For G1 GC,[1] is it the same? The short answer is yes/no and it depends.

In this article, we will demonstrate one case that setting MaxNewSize actually hurts the application's performance using G1 GC.

Live Data Size

To tune the heap size of a Java Application, it's important to find out what its live data size is.  To learn how to estimate a Java application's live data size, read [2].  For the benchmark we are using, its live data size is around 1400 MB. With this benchmark, we are interested in knowing how G1 performs with MaxNewSize set to 400MB and Java heap set to 2GB.

Regularly we use the following settings for the G1 tuning:
  • -Xms2g -Xmx2g -XX:+UseG1GC
plus some options for mixed GC (read [3]). So, for this experiment, we have added MaxNewSize setting like this:
  • -Xms2g -Xmx2g -XX:+UseG1GC -Xmn400m
This has turned out hurting the performance a lot. Note that -Xmn400m is the optimal setting of our benchmark if Parallel GC is used.

Concurrent Cycle in G1 GC

G1 has four main operations:[5]
  • A young collection
  • A background, concurrent cycle
  • A mixed collection
  • If necessary, a full GC

Without much ado, read [5-9] for the needed background of G1 GC.

G1 is a concurrent collector.  Its concurrent cycle has multiple phases—some of which stop all application threads (denoted by STW) and some of which do not:
  • Initial-mark (STW)
    • Denoted by: 
      • [GC pause (G1 Evacuation Pause) (young) (initial-mark)
      • [GC pause (Metadata GC Threshold) (young) (initial-mark)
  • Root Region Scan
    • Denoted by: 
      • [GC concurrent-root-region-scan-start]
      • [GC concurrent-root-region-scan-end
  • Concurrent marking
    • Denoted by:
      • [GC concurrent-mark-start]
      • [GC concurrent-mark-end
    • This phase cannot be interrupted by a young collection
  • Remark (STW)
    • Denoted by:
      • [GC remark
    • Also does reference processing
  • Cleanup (STW)
    • Denoted by:
      • [GC cleanup 1936M->1931M(2048M)
  • Concurrent cleanup:
    • Single-threaded
      • Denoted by:
        • [GC concurrent-cleanup-start]
        • [GC concurrent-cleanup-end

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.  During the concurrent cycle, young garbage collections are allowed, which are triggered when eden fills up (note that initial-mark is implemented using a young collection cycle) .

The set of live objects after marking cycle is composed of the live objects in the snapshot, and the objects allocated since the start of the marking cycle. The G1 GC marking algorithm uses a pre-write barrier to record and mark objects that are part of the logical snapshot.

After the concurrent cycle, we expect to see:[5]
  • The eden regions before the marking cycle have been completely freed and new eden regions have been  allocated
  • Old regions could be more occupied because the promotion of live objects from young regions
  • Some old regions are identified to be mostly garbage and become candidates in later mixed or old collection cycles


The reason of setting -Xmn400m has caused the regression of G1 is:
The option has forced G1 to use a young generation space of up to 400 MB and leaves G1 just 200 MB (i.e. 2048MB - 400MB - 1400MB) breathing room for shuffling live objects around.    
The small free space has negative impact on G1's concurrent cycles, which has caused most marking cycles not being completed in time.  
Before setting -Xmn400m on the command line, we have found only one instance of aborted marking cycle, which is denoted by:
  • [GC concurrent-mark-abort]
After setting it, we have seen marking cycle was aborted 105 times out of 150 instances.  The lesson we have learnt here is that for a tight heap like our benchmark, it's not a good idea to set -Xmn400m for G1.  Without setting MaxNewSize, G1's ergonomics will dynamically adjust young generation space and it turns out that G1 can do a better job in this case.

Differences between Parallel GC and G1 GC

Note that -Xmn400m is the optimal setting for our benchmark if Parallel GC is used.  When we set MaxNewSize to be 400MB for G1, our benchmark regressed.  So, what's the difference between G1 GC and Parallel GC?

Initially, G1 GC was designed to replace CMS [10] for its relatively lower and more predictable pause times.  This is different from the design of Parallel GC which aims for higher throughput.  To help gain higher throughput, Parallel GC tries to:
  • adjust young generation as large as possible and let it run into a full GC
    • In our 4-hour experiments, we usually see around 50 full GC's in Parallel GC
      • However, for G1's performance tuning, we want to avoid full GC's (see [11] for how)
    • Which means more frequent full GC is expected
      • Note that Parallel GC's Full GC pause time is shorter than G1's in the current JDK 8 releases
To conclude, if you upgrade JDK or switch garbage collector,[7] always re-evaluate original optimal VM settings.


Some writings here are based on the feedback from Thomas Schatzl. However, the author would assume the full responsibility for the content himself.


  1. Garbage First Garbage Collector Tuning
  2. JRockit: How to Estimate the Size of Live Data Set
  3. g1gc logs - basic - how to print and how to understand
  4. g1gc logs - Ergonomics -how to print and how to understand
  5. Java Performance: The Definitive Guide (Strongly recommended)
  6. Garbage First Garbage Collector Tuning - Oracle
  7. Our Collectors by Jon Masamitsu
  8. Understanding Garbage Collection
  9. HotSpot VM Performance Tuning Tips
  10. Understanding CMS GC Logs
  11. G1 GC: Tuning Mixed Garbage Collections in JDK 8
  12. G1 GC Glossary of Terms
  13. Learn More About Performance Improvements in JDK 8