为什么说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"
,最低成本将是
- 支持16个字符的数组 – 32B,它在字边界上很好地对齐。
- 指向数组的指针 – 4或8B,具体取决于平台
- 三个
int
用于偏移量,长度和记忆哈希码 – 12B - 2 x对象开销 – 取决于VM,但8B是一个很好的经验法则。
- 一个
int
为数组长度。
因此,大约72B的实际有效载荷构成44.4%。 有效载荷构成更长的字符串。
在Java7中,一些JDK实现正在废除支持数组共享,以避免在内存中固定大型char
[]。 这允许他们取消三个int
的两个。
对于长度为16的字符串,将计算更改为64B,其中实际有效负载占50%。
是否可以使用比Java String更少的内存来保存字符数据? 是。
对于“企业”应用程序(甚至是Android或J2ME应用程序,它们必须通过更少的内存来解决)是否重要? 几乎从不。
过早优化是根源……
与您拥有的其他数据类型相比,它肯定很高。 其他原语使用32位,64位等。
鉴于String
是不可变的,每次对它执行任何操作时,最终都会创建一个新的String
对象,从而消耗更多的内存。