Reputation: 45692
I gonna keep very big data structure Map<Integer, Integer[]>
in memory, there is a risk of going OutOfMemory. Will Map<Integer, Short[]>
decrease a risk or there is no point of using Short[]
instead of Integer[]
?
I'm wondering why two arrays of the same size: Short[]
and Integer[]
consumes the same amount of memory? Here is the output of code below:
Output:
Short primitives array size: 120 b
Int primitives array size: 216 b // It's ok, int takes 4 bytes, short takes 2 bytes
Short array size: 800 b
Int array size: 800 b // WHY?? Why Int[] takes the same amount of memory as Short[]
Short set size: 2960 b //There is no sense to use Set<Short> instead of Set<Integer> in Java, right?
Int set size: 2960 b
MemoryTest.java
private final static Integer MAX_VALUE = 1000;
private final static Integer AVERAGE_COLLECTION_LENGTH = 50;
private final static Random rand = new Random();
public static void main(String[] args) {
Short[] shortArray = genRandomArrayOfShort();
Integer[] intArray = genRandomArrayOfInt();
Set<Short> shortSet = genRandomSetOfShort();
Set<Integer> intSet = genRandomSetOfInt();
System.out.println("Short primitives array size: " + RamUsageEstimator.sizeOfAll(new short[AVERAGE_COLLECTION_LENGTH]) + " b");
System.out.println("Int primitives array size: " + RamUsageEstimator.sizeOfAll(new int[AVERAGE_COLLECTION_LENGTH]) + " b");
System.out.println("Short array size: " + RamUsageEstimator.sizeOfAll(shortArray) + " b");
System.out.println("Int array size: " + RamUsageEstimator.sizeOfAll(intArray) + " b");
System.out.println("Short set size: " + RamUsageEstimator.sizeOfAll(shortSet) + " b");
System.out.println("Int set size: " + RamUsageEstimator.sizeOfAll(intSet) + " b");
}
private static Set<Short> genRandomSetOfShort() {
return Sets.newHashSet(genRandomArrayOfShort());
}
private static Set<Integer> genRandomSetOfInt() {
return Sets.newHashSet(genRandomArrayOfInt());
}
private static Short[] genRandomArrayOfShort() {
Short[] array = new Short[AVERAGE_COLLECTION_LENGTH];
for (int i = 0; i < AVERAGE_COLLECTION_LENGTH; i++) {
array[i] = (short) rand.nextInt(MAX_VALUE);
}
return array;
}
private static Integer[] genRandomArrayOfInt() {
Integer[] array = new Integer[AVERAGE_COLLECTION_LENGTH];
for (int i = 0; i < AVERAGE_COLLECTION_LENGTH; i++) {
array[i] = rand.nextInt(MAX_VALUE);
}
return array;
}
Where RamUsageEstimator
lib could be included to your project with:
<dependency>
<groupId>com.carrotsearch</groupId>
<artifactId>java-sizeof</artifactId>
<version>0.0.5</version>
</dependency>
Upvotes: 1
Views: 243
Reputation: 14159
All Object references have the same size in Java. What you see is the amount of memory required to hold the reference to the actual objects.
Imagine both arrays filled with null
. Shouldn't they both require the same size?
Update: To reduce memory usage, you should use arrays of primitives and not wrapper types. So, using the standard JDK classes, the best you can do is probably using Map<Integer, short[]>
.
You can read about how to calculate memory usage for your data in this blog post.
Upvotes: 4
Reputation: 76
Because Short
and Integer
are both object and not primitive types. Object types are actually just stack references in size of 32/64 bit that point to real values in memory heap. If you want to see real size difference, use short
and int
.
Example:
short[] shortArray;
int[] intArray
Upvotes: 3