我会在内存中保留非常大的数据结构Map<Integer, Integer[]>
,存在OutOfMemory的风险。 Map<Integer, Short[]>
会降低风险,还是无法使用Short[]
代替Integer[]
?
我想知道为什么两个大小相同的数组:Short[]
和Integer[]
消耗相同数量的内存?以下代码的输出如下:
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;
}
RamUsageEstimator
lib可以包含在您的项目中:
<dependency>
<groupId>com.carrotsearch</groupId>
<artifactId>java-sizeof</artifactId>
<version>0.0.5</version>
</dependency>
答案 0 :(得分:4)
所有Object引用在Java中具有相同的大小。您看到的是保存对实际对象的引用所需的内存量。
想象一下两个数组都填充了null
。它们不应该都需要相同的尺寸吗?
更新:要减少内存使用量,您应该使用基元数组而不是包装器类型。因此,使用标准JDK类,您可以做的最好的事情可能是使用Map<Integer, short[]>
。
您可以在此blog post中了解如何计算数据的内存使用情况。
答案 1 :(得分:3)
因为Short
和Integer
既是对象又是基本类型。对象类型实际上只是大小为32/64位的堆栈引用,指向内存堆中的实际值。如果您想查看实际尺寸差异,请使用short
和int
。
例如:
short[] shortArray;
int[] intArray