How to calculate the memory usage of Java objects
As well as knowing the memory usage of common Java objects such as strings, dates, HashMaps etc, it
is sometimes useful to be able to calculate the memory usage of arbitrary objects, given the fields and
references they contain. The information given on this page will generally apply to JVMs based on OpenJDK
using default parameters and are likely to be typical. It is important to note that strictly speaking, however,
they could vary from one JVM to another.
General formula for calculating memory usage of Java objects
In general, the heap memory used by a Java object in Hotspot consists of:
- an object header, consisting of a few bytes of "housekeeping" information;
- memory for primitive fields, according to their size (see below);
- memory for reference fields (4 bytes each);
- padding: potentially a few "wasted" unused bytes after the object data, to make
every object start at an address that is a convenient multiple of bytes and reduce the number of
bits required to represent a pointer to an object.
Sizes of primitive types
In case you're not familiar with the byte size of the different Java primitive data types,
here is the complete list:
Java primitive type | Bytes required for Java primitive |
boolean | 1 |
byte |
char | 2 |
short |
int | 4 |
float |
long | 8 |
double |
You may have expected a boolean to take up a single bit, or an eighth of a byte,
especially if an object had 8 boolean fields. In practice, for efficiency, the JVM will
allocate a whole byte to each boolean. (This also means that the space taken up by a boolean array will
be eight times greater than the theoretical requirement!)
Object overhead for "housekeeping" information
Instances of an object on the Java heap don't just take up memory for their actual fields.
Inevitably, they also require some "housekeeping" information, such as recording an object's
class, ID and status flags such as whether the object is currently reachable, currently
synchronization-locked etc.
In Hotspot, the following generally holds:
- a normal object requires 12 bytes of "housekeeping" space (note that this was 8 bytes in
earlier JVMs);
- arrays require 16 bytes (the same as a normal object, plus 4 bytes for the array length).
Object size granularity (alignment)
In Hotspot, every object occupies a number of bytes that is a multiple of 8. With default settings, if the
number of bytes required by an object for its header and fields is not a multiple 8, then you
round up to the next multiple of 8. In recent JVMs, the so-called object alignment is
a tunable parameter (because the number of bits of alignment do not need to be specified in address offsets, the
alignment also determines the overall size of heap that can be addressed).
The 8-byte object alignment rule in Java means, for example, that:
- a bare Object takes up 16 bytes (12 bytes of housekeeping aligned to the next 8-byte boundaryt);
- an object with one int field (including a boxed Integer) will also take up 16 bytes;
- an object with one long field (including a Java Date) will take up 24 bytes: 12 bytes of header,
8 bytes of data, then 4 bytes of padding to round up to an 8-byte boundary;
- an instance with eight boolean fields will also take up 24 bytes: 12 for the header,
8 for the booleans, plus 4 bytes of padding.
The table of memory usage of typical Java objects presented in our introduction was derived from
empirical measurement, and generally reflects the observations above.
Memory used by commomn Java objects, strings and arrays
You may be interested in the following information:
If you enjoy this Java programming article, please share with friends and colleagues. Follow the author on Twitter for the latest news and rants.
Editorial page content written by Neil Coffey. Copyright © Javamex UK 2021. All rights reserved.