✅ Normal case (no resize)
list.add(element);
And the internal array still has room, the memory cost is:
💾 Only the reference to the new element is added (e.g., 4 or 8 bytes depending on JVM architecture).
So:
- No new array allocation
- Just storing a pointer to the object
- Super efficient: O(1) time + tiny memory cost
🚨 When resizing happens
When the internal array is full, calling add()
triggers a resize, which means:
- A new array is created with a larger capacity (usually 1.5× the old size).
- All existing references are copied into the new array.
- The new element is added.
🧠 Memory cost in this case:
- New array: needs memory for
newCapacity
references - Old array: still exists temporarily until garbage collected
- Total temporary memory: roughly (oldCapacity + newCapacity) × reference size
For a large list, this can mean hundreds of KB or even MB of extra memory during a resize.
🔢 Example:
Say your ArrayList
grows from 1,000,000 to 1,500,000 elements:
- Old array: 1,000,000 refs × 4 bytes = ~4 MB
- New array: 1,500,000 refs × 4 bytes = ~6 MB
- Peak temporary memory usage: ~10 MB
(plus memory for the actual objects pointed to, but that’s separate)
✅ Best practice:
If you know in advance how many elements you’ll add, pre-size the list:
ArrayList<Integer> list = new ArrayList<>(1_000_000);
This avoids multiple resizes and reduces memory churn.
🧠 Summary:
Scenario | Additional memory |
---|---|
add() with room | 🟢 Minimal (1 ref) |
add() with resize | 🔴 High (new array + temporary double memory) |
Pre-sized ArrayList | 🟡 Optimal (no resize) |