为什么说Java的字符串内存使用率很高?

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

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

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

谢谢

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

对于不共享支持arrays的"Apple Computers" ,最低成本将是

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

因此,大约72B的实际有效载荷构成44.4%。 有效载荷构成更长的字符串。


在Java7中,一些JDK实现正在废除支持数组共享,以避免在内存中固定大型char []。 这允许他们取消三个int的两个。

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

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

对于“企业”应用程序(甚至是Android或J2ME应用程序,它们必须通过更少的内存来解决)是否重要? 几乎从不。

过早优化是根源……

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

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