Insights and updates on Java SE and OpenJDK from the Java Platform Group Product Management Team

  • March 24, 2016

G1: from garbage collector to waste management consultant

Guest Author

Java’s garbage collection capabilities make it easier for developers to write software and focus on the task at hand, without focusing on freeing up unused memory. In JDK 9, the G1 garbage collector will likely become the default collector and can do more than simply freeing memory. Instead of a simple garbage collector to free up memory, G1 takes the role of a waste management consultant: freeing unused memory and identifying ways to reduce the overall amount of garbage.

String Deduplication may decrease heap usage by about 10%

String objects are among the most commonly used object by almost all applications. Applications often store the same String multiple times for a variety of reasons, either within one class or across many classes. By analyzing these Strings, the JDK can decrease the overall memory needed to store them.String Deduplication may decrease heap usage by about 10%

String deduplication was first introduced in JDK 8 update 20 and operates as a background task. As the G1 garbage collector walks through memory references to clean up, it analyzes Strings to find duplicates and create memory-saving links between them. Similar to other garbage collection tasks, developers do not need to modify any code in order for it to work. An analysis by Fabian Lange from Codecentric found that String deduplication “adds no runtime overhead as it is performed asynchronously and concurrent during garbage collection.”

The following flags are needed to enable String Deduplication on JDK 8:

-XX:+UseG1GC Enables the G1 garbage collector.
-XX:+UseStringDeduplication Enables the String Deduplication feature within G1.
-XX:+PrintStringDeduplicationStatistics Optional flag to analyze what is happening through the command-line.
-XX:StringDeduplicationAgeThreshold=3 Optional flag to change when Strings become eligible for deduplication.

Example: Decreasing memory used by the Eclipse IDE

Eclipse is a popular Integrated Development Environment, helping developers read, write, and construct source code. The G1 garbage collector will typically perform better for long-running applications focused on throughput (e.g. servlet containers), but it can also function well for client applications.

The following example was run on JDK 8u72 with Eclipse Mars. I am also turning on a Java Flight Recording to see the impact on garbage collection, object allocation, and overall memory consumption. I ran the same operations twice: once without –XX:+UseStringDeduplication and the filename of before.jfr, so that I could do somewhat of a comparison.

The following lines can go inside your eclipse.ini at the end:The following lines can go inside your eclipse.ini at the end:

#The lines below are not necessary for G1, I am including them to benchmark the difference
-XX:StartFlightRecording=filename=after.jfr,dumponexit=true,maxage=5m,settings=c:/Users/ecostlow /desktop/Everything-Costlow.jfc

As a background task, String deduplication was taking about 0.0000908 seconds during my brief usage. It probably took longer to print statistics. Although my laptop is not a controlled environment and I manually did the same actions, the overall heap usage went down about 9% from 233MB to 213MB during my five minutes of usage.

JFR of G1 String Deduplication: before and after

Here are the details from the final output of the String Deduplication Statistics (using -XX:+PrintStringDeduplicationStatistics) with some cumulative numbers:

[GC concurrent-string-deduplication, 14.5K->6120.0B(8744.0B), avg 38.6%, 0.0000908 secs]
   [Last Exec: 0.0000908 secs, Idle: 0.8590383 secs, Blocked: 0/0.0000000 secs]
      [Inspected:             142]
         [Skipped:              0(  0.0%)]
         [Hashed:              89( 62.7%)]
         [Known:               21( 14.8%)]
         [New:                121( 85.2%)     14.5K]
      [Deduplicated:           96( 79.3%)   8744.0B( 58.8%)]
         [Young:                0(  0.0%)      0.0B(  0.0%)]
         [Old:                 96(100.0%)   8744.0B(100.0%)]
   [Total Exec: 52/0.1772395 secs, Idle: 52/103.0713572 secs, Blocked: 2/0.1476086 secs]
      [Inspected:          322160]
         [Skipped:              0(  0.0%)]
         [Hashed:          164740( 51.1%)]
         [Known:            61960( 19.2%)]
         [New:             260200( 80.8%)     20.3M]
      [Deduplicated:       144975( 55.7%)   8037.4K( 38.6%)]
         [Young:                2(  0.0%)     72.0B(  0.0%)]
         [Old:             144973(100.0%)   8037.3K(100.0%)]
      [Memory Usage: 4213.1K]
      [Size: 131072, Min: 1024, Max: 16777216]
      [Entries: 132446, Load: 101.0%, Cached: 3622, Added: 170306, Removed: 37860]
      [Resize Count: 7, Shrink Threshold: 87381(66.7%), Grow Threshold: 262144(200.0%)]
      [Rehash Count: 0, Rehash Threshold: 120, Hash Seed: 0x0]
      [Age Threshold: 3]
      [Dropped: 0]

Join the discussion

Comments ( 2 )
  • Rushikesh Sawant Sunday, April 3, 2016

    Good to know this.

    Thank you for sharing this information!

  • guest Friday, April 15, 2016


    Nice job

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.