String vs char []

Bat*_*tty 47 java memory string memory-management

我从IBM获得了一些名为"从Java代码到Java堆:了解应用程序的内存使用情况"的幻灯片,它说,当我们使用String而不是char[],

单个字符的最大开销为24:1!

但是我无法理解这里提到的开销.有人可以帮忙吗?

资源 :

在此输入图像描述

And*_*hev 38

该图与JDK 6-32位有关.

JDK 6

在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

只是为了比较,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.

有用的链接:


Sho*_*ate 9

在JVM中,字符变量存储在单个16位内存分配中,并且更改为该Java变量会覆盖相同的内存位置.这使得创建或更新字符变量的速度非常快且内存便宜,但与JVM的开销相比增加了JVM的开销.字符串中使用的静态分配.

JVM将Java字符串存储在可变大小的内存空间(本质上是一个数组)中,该字符串在创建String对象或首次分配值时,字符串的大小(字符串终止字符加1)完全相同.因此,初始值为"HELP!"的对象 将分配96位存储空间(6个字符,每个大小为16位).这个值被认为是不可变的,让JVM内联引用变量,使静态的字符串赋值非常快,而且非常小巧,再加上非常有效率从JVM的观点.

参考