How Much Memory Does a Java Object Really Use?

Understanding the actual memory footprint of Java objects—including headers, class pointers, fields, and alignment—reveals hidden waste, and the article provides calculations for Integer objects, arrays, and collections, plus practical guidelines to reduce memory usage by preferring primitive types, smaller fields, and arrays over collections.

macrozheng
macrozheng
macrozheng
How Much Memory Does a Java Object Really Use?

When writing Java code, developers usually focus on business logic rather than the exact memory size of a Java object, unaware that a lot of memory can be wasted unintentionally.

How big is a Java object?

To calculate the precise memory consumption of a Java object, you first need to understand its internal structure.

Java object structure

A Java object on the heap consists of three parts:

Object Header

Class Pointer

Fields

Every ordinary Java object has an object header that records the object's state.

Object layout
Object layout

In a 32‑bit environment the layout differs from a 64‑bit one. Example for 32‑bit: hash(25)+age(4)+lock(3)=32bit In a 64‑bit environment: unused(25+1)+hash(31)+age(4)+lock(3)=64bit The class pointer points to the object's superclass. On a 32‑bit JVM it occupies 4 bytes; on a 64‑bit JVM it is 4 bytes when compressed oops are enabled (or the heap is < 32 GB), otherwise 8 bytes.

Fields refer to instance fields only; static fields are shared and not counted here.

Example: calculating the size of java.lang.Integer on a 32‑bit system.

Object Header (4 bytes) + Class Pointer (4 bytes) = 8 bytes. The only instance field is the integer value:

/**
 * The value of the <code>Integer</code>.
 *
 * @serial
 */
private final int value;

An int occupies 4 bytes, so the raw size is 4 + 4 + 4 = 12 bytes. However, Java objects are aligned to 8‑byte boundaries, so 4 bytes of padding are added, resulting in 16 bytes.

Arrays are a special kind of object that include an extra length field (an int).

For int[] arr = new int[10]; the heap size is:

4 (object header) + 4 (pointer) + 4 (length) + 4*10 (elements) = 52 bytes → aligned to 56 bytes

Memory‑saving principles

Knowing object memory usage lets us see that a java.lang.Integer consumes 16 bytes while a primitive int uses only 4 bytes—a 4:1 ratio.

1) Prefer primitive types over wrapper types

When designing database schemas or JavaBeans, choose the smallest suitable primitive type (e.g., short, byte, boolean) instead of larger wrappers.

For example, a long uses 4 bytes more than an int. If you have one million long values, that’s roughly 4 MB of unnecessary memory.

2) Choose the smallest field type that meets capacity requirements

Consider an ArrayList holding ten numbers. Its memory breakdown is:

/**
 * The array buffer into which the elements of the ArrayList are stored.
 */
private transient Object[] elementData;

/**
 * The size of the ArrayList (the number of elements it contains).
 */
private int size;

Object Header (4 bytes) + Pointer (4 bytes) + size (4 bytes) + elementData array object (12 bytes) + ten Integer objects (10 × 16 bytes) = 184 bytes.

Replacing the list with an int[] uses 12 bytes for the array object plus 4 × 10 = 52 bytes for the elements, aligned to 56 bytes. The ratio of list to array memory is roughly 184:56 (> 3:1).

3) Prefer arrays over collections when possible

Arrays can store primitive types directly, while collections store only wrapper objects.

If a collection is unavoidable, consider memory‑efficient libraries such as fastutil.

4) Small tricks

Represent timestamps with long or int instead of Date or String.

If short strings can be enumerated or represented as ASCII, store them as long or int.

These tricks depend on the specific data and can be applied aggressively when memory is critical.

Conclusion

Performance and readability often conflict; when memory savings are essential, you may need to sacrifice some readability. The principles above provide practical ways to reduce Java heap usage in real‑world applications.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaPerformance OptimizationMemory ManagementBackend DevelopmentObject Layout
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.