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

标签 java memory-management

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

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

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

最佳答案

因为我没有生活,所以我呈现无聊的结果。请注意,由于愚蠢的错误等原因,这几乎可以保证是不准确的。二手this寻求帮助,但我不太确定准确性。我可以阅读 JVM 规范,但我没有那么空闲时间。

由于关注的对象内部存在大量字段,而且我对对象的开销有多少以及填充的位置存在一些不确定性,因此该计算变得相当复杂。如果没记错的话,对象有 8 个字节保留给 header 。顺便说一句,这都是针对 64 位 VM 的。我认为,它与 32 位 VM 之间的唯一区别是引用的大小。

做法总结:获取源码,递归累加所有字段所需空间。需要了解 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字节供引用

char[10]定义:

  1. 对象头 - 8 字节
  2. int length - 4 个字节
  3. char x10 - 2 字节 * 10 = 20 字节

ObjectStreamField[0]定义:

  1. 对象头 - 8 字节
  2. int length - 4 字节 + 4 字节填充

单个总计String长度为 10:88 字节

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


HashSet定义:

  1. 对象头 - 8 字节
  2. long serialVersionUID - 8 个字节
  3. Object PRESENT - 8 个字节
  4. HashMap<E, Object> map - 8 个字节

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 个字节

Node定义:

  1. 对象头 - 8 字节
  2. int hash - 4 字节 + 4 字节填充
  3. K key - 8 个字节
  4. V value - 8 个字节
  5. Node<K, V> next - 8 个字节

Node<K, V>[]如果我记得 HashMap 应该有 2048 的大小作品。所以它定义了:

  1. 对象头 - 8 字节
  2. int length - 4 字节 + 4 字节填充
  3. Node<K, V>引用 * 2048 - 8 字节 * 2048 = 16384 字节。

所以 HashSet应该是:

  1. 32 字节仅用于 HashSet
  2. HashMap 为 64 字节
  3. 每个 Node<K, V> 40 个字节里面Node<K, V>[] * 1000 个节点 = 40000 字节
  4. 16400 字节 Node<K, V>[]HashMap里面

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


所以至少根据我的计算,占用的总空间应该在 144496 字节左右——大约 141 KB(迂腐的是 kibibytes)。老实说,这似乎有点小,但这是一个开始。

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

关于一组字符串的Java对象内存大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24253710/

相关文章:

java - 在 RxJava2 中正确使用 Single 和控制流

java - 在java中通过cfml将 Crystal 报表导出为PDF

java - 将 Tomcat 配置为使用 cacerts 以外的信任库

ios - swift 内存泄露怎么办?

java - 如何正确设置能够运行模拟的 Canvas

java - 在枚举上写入 Parcelable 会使应用程序崩溃

multithreading - 操作系统如何确定应为每个线程分配多少堆栈空间?

ios - 为什么会出现 4 MB 使用率和 320 MB 可用内存警告?

c - "memory is 8 bytes aligned"是什么意思?

c++ - 为什么删除的内存无法使用? C++