I tried to check the memory consumption of a program. During the check, I have noticed some interesting things.
I created a Load class, which contains some fields.
class Load {
String name;
String title;
long id;
}
I created 500000 Load objects and add them to an ArrayList. I have found, it took around 18 MB of memory.
Then, I modified the Load class and use reference type Long.
class Load {
String name;
String title;
Long id;
}
Again created 500000 Load objects and add them to ArrayList. Interestingly this time it took less memory than the previous one. It way 14 MB.
Run test changing os and JVM version. Found the following results.
OS: Windows 10 Pro 64 bit
JDK: 11 64bit
Object Created | Load Object | Memory | Load Object | Memory
------------------------------------------------------------------------------
1. 500000 | With primitive long | 18 MB | With reference Long | 14 MB
2. 900000 | | 32 MB | | 26 MB
3. 1500000 | | 53 MB | | 41 MB
OS: macOS Big Sur 64 bit
JDK: 8 64bit
Object Created | Load Object | Memory | Load Object | Memory
------------------------------------------------------------------------------
1. 500000 | With primitive long | 18 MB | With reference Long | 14 MB
2. 900000 | | 32 MB | | 26 MB
3. 1500000 | | 53 MB | | 41 MB
Surprisingly, in all of these test runs, Object contains primitive types long consume more memory than Object contains reference Long.
My question is, why primitive type takes more memory in this scenario?
Memory Tester Code:
public class MemoryChecker {
private static final long MEGABYTE = 1024L * 1024L;
public static long bytesToMegabytes(long bytes) {
return bytes / MEGABYTE;
}
public static void main(String[] args) {
List<Load> list = new ArrayList<Load>();
for (int i = 0; i <= 500000
; i++) {
list.add(new Load("Jim", "Knopf", 11L));
}
// Get the Java runtime
Runtime runtime = Runtime.getRuntime();
// Run the garbage collector
runtime.gc();
// Calculate the used memory
long memory = runtime.totalMemory() - runtime.freeMemory();
System.out.println("Used memory is megabytes: " + bytesToMegabytes(memory));
}
}
Complete code git repo.