字符串与字符[]
2022-09-01 00:08:37
我有一些来自IBM的幻灯片,名为:“从Java代码到Java堆:了解应用程序的内存使用情况”,也就是说,当我们使用而不是时,有String
char[]
单个字符的最大开销为 24:1!
但我无法理解这里指的是什么开销。任何人都可以帮忙吗?
源:
我有一些来自IBM的幻灯片,名为:“从Java代码到Java堆:了解应用程序的内存使用情况”,也就是说,当我们使用而不是时,有String
char[]
单个字符的最大开销为 24:1!
但我无法理解这里指的是什么开销。任何人都可以帮忙吗?
源:
此图与 JDK 6- 32 位有关。
在 Java-7 之前的世界中,作为指向数组区域的指针实现的世界字符串:char[]
// "8 (4)" reads "8 bytes for x64, 4 bytes for x32"
class String{ //8 (4) house keeping + 8 (4) class pointer
char[] buf; //12 (8) bytes + 2 bytes per char -> 24 (16) aligned
int offset; //4 bytes -> three int
int length; //4 bytes -> fields align to
int hash; //4 bytes -> 16 (12) bytes
}
所以我数了数:
36 bytes per new String("a") for JDK 6 x32 <-- the overhead from the article
56 bytes per new String("a") for JDK 6 x64.
相比之下,在JDK中,7+是一个仅包含缓冲区和字段的类。String
char[]
hash
class String{ //8 (4) + 8 (4) bytes -> 16 (8) aligned
char[] buf; //12 (8) bytes + 2 bytes per char -> 24 (16) aligned
int hash; //4 bytes -> 8 (4) aligned
}
所以它是:
28 bytes per String for JDK 7 x32
48 bytes per String for JDK 7 x64.
更新
有关比率,请参阅下面@Andrey的解释。随着字符串长度的增长,此比例降至 1。3.75:1
有用的链接:
在 JVM 中,字符变量存储在单个 16 位内存分配中,并且对该 Java 变量的更改将覆盖相同的内存位置。这使得创建或更新字符变量非常快且内存便宜,但与字符串中使用的静态分配相比,JVM 的开销增加了。
JVM 将 Java 字符串存储在可变大小的内存空间(实质上是数组)中,该内存空间与创建 String 对象或首次为其赋值时的字符串大小完全相同(对于字符串终止字符加 1)。因此,初始值为“HELP!”的对象将被分配 96 位存储(6 个字符,每个大小为 16 位)。此值被认为是不可变的,允许 JVM 内联对该变量的引用,使静态字符串赋值非常快速、非常紧凑,而且从 JVM 的角度来看非常有效。