我将String数组声明为:
String[] items1 = new String[5];
String[] items2 = new String[20];
如果两个数组都只包含2个元素,那么这两个数组对内存和性能的影响有多大。
答案 0 :(得分:3)
单维数组是单个对象。正如所料,该数组具有通常的对象头。但是,此对象头是12个字节以容纳四字节数组长度。然后是实际的数组数据,正如您所料,它由元素数乘以一个元素所需的字节数组成,具体取决于其类型。对于一个对象引用,一个元素的内存使用量是4个字节;有关基本类型的内存使用情况列表,请参阅Java数据类型的页面。如果数组的总内存使用量不是8字节的倍数,则将大小向上舍入到下一个8的mutlitple(就像任何其他对象一样)。
答案 1 :(得分:3)
您可以自己测试一下。
public static void main(String... args) {
long free1 = free();
String[] two = new String[2];
long free2 = free();
String[] twenty = new String[20];
long free3 = free();
if (free3 == free1) System.err.println("You need to use -XX:-UseTLAB");
System.out.println("String[2] took " + (free1 - free2) + " bytes and String[20] took " + (free2 - free3) + " bytes.");
}
private static long free() {
return Runtime.getRuntime().freeMemory();
}
打印
String[2] took 24 bytes and String[20] took 96 bytes.
所以你可能会浪费72个字节的内存。如果你的内存每GB花费10美元,你可能会浪费0.000072美分的内存。但是,你的第二个时间可能值2美分。在这种情况下,在这种情况下,实际上不值得花费一毫秒的时间来担心它。即写20而不是2所需的时间远远超过了它。
答案 2 :(得分:2)
使用新的关键字,您可以将与其大小相关联的数组定义到内存中,因此无论您是将值存储在全部还是部分中,都依赖于您。如果你需要动态,那么更喜欢使用list对象作为动态的arraylist,而数组是预定义类型,所以在此之后它不会减少或增加它的大小,因为你必须用它的新大小创建新的数组对象
答案 3 :(得分:2)
效果可以忽略不计,因为您所做的只是分别存储额外的3和18个空引用。存储额外的空引用不会显着增加内存占用,也不会显着影响代码的性能。
但是,如果您事先知道,您要存储多少元素,则似乎不需要5或20个元素数组。
答案 4 :(得分:0)
这取决于这两个元素的大小。
答案 5 :(得分:0)
两者都只包含对字符串的引用,因此String [5]使用两个元素的内存等于String [5]使用0个元素的内存。 String [20]也是如此。
现在元素使用的内存是另一回事。
答案 6 :(得分:0)
Consumed_HEAP(items1) = (POINTER_SIZE*5) + Consumed_HEAP(items1[0])+Consumed_HEAP(items1[1]) + ARRAY_METADATA
Consumed_HEAP(items2) = (POINTER_SIZE*20) + Consumed_HEAP(items2[0])+Consumed_HEAP(items2[1]) + ARRAY_METADATA
POINTER_SIZE = x86 ? 4 : x64 ? 8 : ...
Consumed_HEAP(str) = str.length() * 2 + SOME_JVM_SPECIFIC_HEAP_FOR_STRING_REFERENCE_TYPE (~ 16-20)
SOME_JVM_SPECIFIC_HEAP_FOR_STRING_REFERENCE_TYPE contains of all String fields:
1. reference from string to char array
2. memoized hash
3-n. other fields
n+1. link to class object