Java tutorial index  Java memory usage (index)  Memory usage of objects  Array memory usage  Memory instrumentation  Java 5 profiling (introduction)  ThreadMXBean

Memory usage of Java Strings and string-related objects (ctd)

In part one of this discussion, we looked at the memory usage of a Java String. But a String isn't the only way to store character in memory data in Java. Other objects can be used, with differing memory usage:

  • the StringBuffer and (as of Java 5) StringBuilder classes store just the buffer for the character data plus current length (without the additional offset and hash code fields of a String), but that buffer could be larger than the actual number of characters placed in it;
  • if it suits our needs, we are free to implement any old CharSequence that we wish and potentially make it take up less space than a String, StringBuffer or StringBuilder.

Memory usage of StringBuilder and StringBuffer

These classes are essentially implemented in the same way via a shared subclass and their memory usage is identical. They differ in that methods on StringBuffer are (fairly pointlessly, but for backwards compatibility) synchronized. For simplicity, we'll refer to them generically as "string buffers" from now on, but our comments on memory usage apply to both classes.

A string buffer requires the overhead of the object itself (from our discussion of Java object memory usage recall that this is 8 bytes in Hotspot), space for an int field (for the character count) and space for a reference to the underlying char array. This comes to 16 bytes, and no "padding" is required. The char arary in turn requires 12 bytes of overhead (as do arrays generally), then two bytes per character capacity, rounding up to the next multiple of 8 as required. So if the buffer is initialised to a 16 character capacity (the deafult for a newly-created "empty" buffer), this gives 16+12+(16*2)=60, rounded up to 64 bytes.

It is important to note that when we call append(), the capacity of a string buffer doubles until it can hold the next character to be added. Thus, creating a default string buffer and then adding 17 characters will leave it with a capacity of 16*2=32 characters, each character position needing two bytes. and its memory usage will be 16+12+(32*2)=92, rounded up to 96 bytes.

Memory usage of a String created from a string buffer

As of Java 5, a String created from a string buffer takes up just enough space to accommodate the characters in the string (and the usual String overhead), as per the String memory usage formula given on the previous page. (In previous versions of Java, the String could occupy more space as it "borroewd" the same char buffer from the StringBuffer.)

Next: reducing memory used by Strings

Given the information presented so far, we consider how to reduce the amount of memory occupied by Strings in a Java application.


Written by Neil Coffey. Copyright © Javamex UK 2011. All rights reserved.