Bat*_*tty 47 java memory string memory-management
我从IBM获得了一些名为"从Java代码到Java堆:了解应用程序的内存使用情况"的幻灯片,它说,当我们使用String而不是char[],
单个字符的最大开销为24:1!
但是我无法理解这里提到的开销.有人可以帮忙吗?
资源 :

And*_*hev 38
该图与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
}
Run Code Online (Sandbox Code Playgroud)
所以我算了一下:
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.
Run Code Online (Sandbox Code Playgroud)
只是为了比较,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
}
Run Code Online (Sandbox Code Playgroud)
所以这是:
28 bytes per String for JDK 7 x32
48 bytes per String for JDK 7 x64.
Run Code Online (Sandbox Code Playgroud)
UPDATE
有关3.75:1比例,请参阅下面的@ Andrey的解释.随着弦长的增长,这个比例下降到1.
有用的链接:
在JVM中,字符变量存储在单个16位内存分配中,并且更改为该Java变量会覆盖相同的内存位置.这使得创建或更新字符变量的速度非常快且内存便宜,但与JVM的开销相比增加了JVM的开销.字符串中使用的静态分配.
JVM将Java字符串存储在可变大小的内存空间(本质上是一个数组)中,该字符串在创建String对象或首次分配值时,字符串的大小(字符串终止字符加1)完全相同.因此,初始值为"HELP!"的对象 将分配96位存储空间(6个字符,每个大小为16位).这个值被认为是不可变的,让JVM内联引用变量,使静态的字符串赋值非常快,而且非常小巧,再加上非常有效率从JVM的观点.