14

在这篇文中,据说 String 的最小内存使用量是:

8 * (int) ((((no chars) * 2) + 45) / 8)字节。

因此,对于字符串“Apple Computers”,最小内存使用量为 72 字节。
即使我有 10,000 个两倍长度的 String 对象,内存使用量也将小于 2Mb,这根本不算多。那么这是否意味着我低估了企业应用程序中存在的字符串数量,或者那个公式是错误的?

谢谢

4

3 回答 3

17

Java 中的字符串存储取决于字符串的获取方式。支持char数组可以在多个实例之间共享。如果不是这种情况,您将拥有通常的对象开销以及一个指针和三个ints 的存储空间,这通常会产生 16 个字节的开销。然后后备数组每个需要 2 个字节,char因为chars 是 UTF-16 代码单元。

对于"Apple Computers"不共享后备阵列的情况,最小成本将是

  1. 16 个字符的后备数组——32B,在字边界上很好地对齐。
  2. 指向数组的指针 - 4 或 8B,具体取决于平台
  3. int偏移量、长度和记忆哈希码的三个s - 12B
  4. 2 x 对象开销 - 取决于 VM,但8B是一个很好的经验法则。
  5. 一个int用于数组长度。

所以大约 72B,其中实际有效载荷占 44.4%。对于更长的字符串,有效负载构成更多。


在 Java7 中,一些 JDK 实现取消了支持数组共享,以避免将大char的 [] 固定在内存中。这使他们可以取消三个ints 中的两个。

这会将长度为 16 的字符串的计算更改为 64B,其中实际有效负载占 50%。

于 2012-06-21T03:22:40.733 回答
3

是否可以使用比 Java 字符串更少的内存来保存字符数据?是的。

这对“企业”应用程序(甚至是 Android 或 J2ME 应用程序,它们必须使用更少的内存)有影响吗?几乎从不。

过早的优化是根本...

于 2012-06-21T03:25:10.173 回答
1

与您拥有的其他数据类型相比,它肯定很高。其他原语使用 32 位、64 位等。

鉴于它String是不可变的,每次对它执行任何操作时,最终都会创建一个新String对象,从而消耗更多内存。

于 2012-06-21T03:22:28.687 回答