Friends of OpenJDK Today

Compact Strings: Reclaim 25% of Java Heap Memory & Lower Your Cloud Bills

September 24, 2021

Author(s)

  • A N M Bazlur Rahman

    A N M Bazlur Rahman is a Software Engineer with over a decade of specialized experience in Java and related technologies. His expertise has been formally recognized through the prestigious ... Learn more

Did you know that you can save up to 25% of your heap memory and your Cloud bills without any effort? Well, it's true. Many exciting features have been added to the latest releases of Java recently and I'm going to cover one that is often overlooked in this article.

We all know that Strings are the most used Object in any Java application. In fact, they probably take up almost half of the heap size of any Java application. Before delving into this much further, let me answer your obvious question: what are Strings made of?

Well, Strings are nothing but an array of characters, well, at least, this is how it used to be. If you open the String class from JDK 8, you will be able to confirm this. However, when looking at it the other way around, and unlike in C, an array of char is not a String in Java, and neither a String nor an array of char is terminated by '\u0000' (the NULL character).

Nevertheless, a String object in Java is also immutable, which means the String content never changes, while an array of char has mutable elements. Reference: https://docs.oracle.com/javase/specs/jls/se14/html/jls-10.html#jls-10.9. I will write about String immutability in another article.

In Java 8 and pre-Java 8, a char array is used in a String. A char takes two bytes of memory. That means that to store one character, you need 16 bits of memory. For example, if you write “Hello” you'd need an object of an array, and that would have 5 characters.

The total size of a String 
= size of array object itself + size of 5 characters + array holds an integer for its length 
= 8 bytes for array object header + 5 * 2bytes + 4 bytes 
= 8 + 10 + 4 
= 22 bytes

However, most Western locales nowadays need only 8 bits byte array to encode them. That's why Java 11 (see JEP 254) introduces the new compact Strings that encode a string with an 8-bit byte array instead of a char array. Unless they explicitly need 16-bit characters. These strings are known as compact strings. Hence, the size of an average string in Java 11 is roughly half the size of the same in Java 8.

On average, 50% of a typical Java heap may be consumed by String objects. This will vary from application to application, but on average, the heap requirement for such a program running with Java 11 is only 75% of that same program running in Java 8.

This is a huge saving.

The -XX:+CompactStrings flag controls this feature.

If you want to disable it, use the -XX:-CompactStrings flag.

Topics:

Related Articles

View All
  • 7 Functional Programming Techniques in Java: A Primer

    There is a lot of hype around functional programming (FP) and a lot of cool kids are doing it but it is not a silver bullet.

    Like other programming paradigms/styles, functional programming also has its pros and cons and one may prefer one paradigm over the other.

    If you are a Java developer and wants to venture into functional programming, do not worry, you don’t have to learn functional programming oriented languages like Haskell or Clojure(or even Scala or JavaScript though they are not pure functional programming languages) since Java has you covered and this post is for you.

    Read More
    May 11, 2021
  • A Real-World Example of a Stream Collector

    You can solve most use cases with one of the out-of-the-box collectors provided in the Collectors class.

    However, some require to implement a custom Collector, e.g., when you need to collect more than a single collection or a single scalar.

    While it may seem complicated if you never developed one before, it’s not. You only need a bit of practice.

    I hope this article might help you with it!

    Read More
    May 07, 2021
  • Project Panama for Newbies (Part 1)

    In this series of articles, we will explore the APIs from OpenJDK’s Project Panama.

    My intent is to show you how to be proficient in using the Foreign Linker APIs (module ‘jdk.incubator.foreign’) as it relates to Java interoperability with native code.

    While this article is for newbies, I assume you know the basics of the Java language, a little bash scripting, and a familiarity with C programming concepts. If you are new to C language don’t worry I will go over the concepts later.

    Read More
    August 10, 2021

Author(s)

  • A N M Bazlur Rahman

    A N M Bazlur Rahman is a Software Engineer with over a decade of specialized experience in Java and related technologies. His expertise has been formally recognized through the prestigious ... Learn more

Comments (0)

Your email address will not be published. Required fields are marked *

Highlight your code snippets using [code lang="language name"] shortcode. Just insert your code between opening and closing tag: [code lang="java"] code [/code]. Or specify another language.

Save my name, email, and website in this browser for the next time I comment.

Subscribe to foojay updates:

https://foojay.io/feed/
Copied to the clipboard