Back to results for “Objects”
Java › Arrays & Multidimensional Arrays

How does the JVM lay out array objects in memory, including the array header overhead, and how does this affect memory efficiency for very large arrays of primitives versus boxed wrapper types?

Advanced

Answer

A Java array is itself an object on the heap, carrying an object header (typically 12-16 bytes on a 64-bit JVM, including a mark word and class pointer) plus a 4-byte length field, followed by the actual element data laid out contiguously -- a primitive array (like int[]) stores raw values directly and compactly in this contiguous block, while an array of boxed wrapper types (Integer[]) instead stores references (pointers) to separately-heap-allocated Integer objects, meaning each element incurs both the pointer's own 4-8 bytes AND a separate object header for each boxed Integer instance, resulting in dramatically higher memory usage and worse cache locality for large numeric datasets.
// Primitive array: compact, contiguous memory, ~16 bytes header + 4 bytes per int
int[] primitiveArray = new int[1_000_000];  // roughly 4MB total

// Boxed array: each element is a separate heap object plus a reference
Integer[] boxedArray = new Integer[1_000_000];  // roughly 20MB+ total (references + individual Integer objects)
Real-world example A scientific computing application processing millions of numeric data points switches from using an Integer[] (or a generic List<Integer>) to a raw int[] array after profiling revealed the boxed representation was consuming roughly 4-5x more heap memory and causing significantly worse CPU cache performance due to pointer-chasing through scattered Integer objects.

Common follow-ups: How does the JIT compiler's escape analysis sometimes mitigate boxing overhead in tight loops?;What is the memory layout difference between a 2D primitive array and a flattened 1D equivalent?