Java对象内存大小的一组字符串

时间:2014-06-16 23:32:55

标签: java memory-management

我有一个1000字符串的哈希集。每个字符串的大小为10。

你能告诉我在内存中存储它所需的确切字节数吗?适用于32位和64位虚拟机。

你能解释计算这个的方法吗?

1 个答案:

答案 0 :(得分:7)

因为我没有生命,所以我呈现了无聊的结果。请注意,由于愚蠢的错误等原因,这几乎可以保证不准确。使用this求助,但我对准确性不太了解。我可以读取JVM规范,但我没有那个空闲时间。

由于所关注对象中存在大量字段,这个计算变得相当复杂,加上我对于对象有多少开销以及填充位置的不确定性。如果内存服务,则对象具有为标头保留的8个字节。顺便说一下,这对于64位VM来说都是如此。我认为,只有32位虚拟机之间的差异就是参考的大小。

如何执行此操作的摘要:获取源代码,并递归地添加所有字段所需的空间。需要了解VM如何工作以及实现如何工作。

String开始。 String定义:

  1. 对象标头 - 8个字节
  2. long serialVersionUID - 8个字节
  3. int hash - 4个字节+ 4个字节填充
  4. char[] value(在您的情况下设置为char[10]) - 8个字节供参考
  5. ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0] - 8个字节供参考
  6. char[10]定义:

    1. 对象标头 - 8个字节
    2. int length - 4个字节
    3. char x10 - 2个字节* 10 = 20个字节
    4. ObjectStreamField[0]定义:

      1. 对象标头 - 8个字节
      2. int length - 4个字节+ 4个字节填充
      3. 长度为10:88字节的单个String的总计

        1000 String的总计,长度为10:88000字节。


        HashSet定义:

        1. 对象标头 - 8个字节
        2. long serialVersionUID - 8个字节
        3. Object PRESENT - 8个字节
        4. HashMap<E, Object> map - 8个字节
        5. HashMap定义(在Java 8中)(忽略按需创建的内容,如EntrySet):

          1. 对象标头 - 8个字节
          2. long serialVersionUID - 8个字节
          3. int DEFAULT_INITIAL_CAPACITY - 4个字节
          4. int MAXIMUM_CAPACITY - 4个字节
          5. int TREEIFY_THRESHOLD - 4个字节
          6. int UNTREEIFY_THRESHOLD - 4个字节
          7. int MIN_TREEIFY_CAPACITY - 4个字节
          8. int size - 4个字节
          9. int modcount - 4个字节
          10. int threshold - 4个字节
          11. float DEFAULT_LOAD_FACTOR - 4个字节
          12. float loadFactor - 4个字节
          13. Node<K, V>[] table - 8个字节
          14. Node定义:

            1. 对象标头 - 8个字节
            2. int hash - 4个字节+ 4个字节填充
            3. K key - 8个字节
            4. V value - 8个字节
            5. Node<K, V> next - 8个字节
            6. 如果我记得Node<K, V>[]是如何工作的,那么

              HashMap的大小应该是2048。所以它定义了:

              1. 对象标头 - 8个字节
              2. int length - 4个字节+ 4个字节填充
              3. Node<K, V>引用* 2048 - 8字节* 2048 = 16384字节。
              4. 所以HashSet应该是:

                1. 只有HashSet
                2. 的32个字节
                3. 只有HashMap
                4. 的64个字节
                5. Node<K, V>内每Node<K, V>[]个40个字节* 1000个节点= 40000个字节
                6. Node<K, V>[]
                7. HashMap的16400字节

                  总计:HashSet的56496字节,未考虑String内容


                  因此,至少根据我的计算,所占用的总空间应该在144496字节左右 - 大约141千字节(迂腐的kibibytes)。说实话,这似乎不仅仅是一个小问题,但它是一个开始。

                  我目前无法让Instrumentation界面正常工作,所以我无法仔细检查。但如果有人知道他/她正在做什么评论指出我的错误将是受欢迎的。