【问题标题】:String[] Memory UsageString[] 内存使用
【发布时间】:2011-12-09 12:37:25
【问题描述】:

我将一个字符串数组声明为:

String[] items1 = new String[5];
String[] items2 = new String[20];

如果这两个数组都只包含 2 个元素,那么这两个数组会对内存和性能产生多大影响。

【问题讨论】:

    标签: java arrays string


    【解决方案1】:

    你可以自己测试一下。

    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】:

      一维数组是一个对象。正如预期的那样,该数组具有通常的对象头。然而,这个对象头是 12 个字节以容纳一个四字节的数组长度。然后是实际的数组数据,如您所料,它由元素数乘以一个元素所需的字节数组成,具体取决于其类型。对于一个对象引用,一个元素的内存使用量为 4 个字节;有关原始类型的内存使用列表,请参阅 Java 数据类型页面。如果数组的总内存使用量不是 8 字节的倍数,则将大小向上舍入到下一个 8 倍数(就像任何其他对象一样)。

      请看这里:How to calculate the memory usage of a Java array

      【讨论】:

        【解决方案3】:

        使用新关键字,您可以将与其大小关联的数组定义到内存中,因此取决于您是在全部还是部分中存储值。如果您需要动态,那么在数组是预定义类型时更喜欢使用列表对象作为动态的数组列表,因此之后它不会减少或增加它的大小,因为您必须创建具有新大小的新数组对象

        【讨论】:

          【解决方案4】:

          效果可以忽略不计,因为您所做的只是分别存储额外的 3 个和 18 个空引用。存储额外的空引用不会显着增加内存占用,也不会显着影响代码的性能。

          但是,如果您事先知道要存储多少个元素,似乎不需要 5 或 20 个元素的数组。

          【讨论】:

            【解决方案5】:

            这取决于这两个元素的大小。

            【讨论】:

            • 我认为 OP 意味着两个数组中的两个元素相同。
            • 我想强调如果不注意细节,这些事情会变得多么棘手。
            【解决方案6】:

            两者都只包含对字符串的引用,因此具有两个元素的 String[5] 使用的内存等于具有 0 个元素的 String[5] 使用的内存。 String[20] 也是如此。

            现在元素使用的内存是另一回事了。

            【讨论】:

              【解决方案7】:
              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
              

              【讨论】:

                猜你喜欢
                • 2015-10-26
                • 1970-01-01
                • 2012-10-16
                • 2011-03-26
                • 2019-07-09
                • 1970-01-01
                • 2011-03-24
                • 1970-01-01
                • 2011-08-27
                相关资源
                最近更新 更多