我通过将 String
分解成其组成部分来比较在 java 中存储 String
的各种方法。我有这个代码片段:
final String message = "ABCDEFGHIJ";
System.out.println("As String " + RamUsageEstimator.humanSizeOf(message));
System.out.println("As byte[] " + RamUsageEstimator.humanSizeOf(message.getBytes()));
System.out.println("As char[] " + RamUsageEstimator.humanSizeOf(message.toCharArray()));
这是使用 sizeof来测量物体的大小。以上结果显示:
As String 64 bytes
As byte[] 32 bytes
As char[] 40 bytes
鉴于 byte
是 8 位而 char
是 16 位,为什么结果分别不是 10 字节和 20 字节?
此外,String
对象的开销是基础 byte[]
的两倍?
这是在使用
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
在 OSX 上
最佳答案
以下数据适用于 Hotspot/Java 8 - 其他 JVM/Java 版本的数字会有所不同(例如,在 Java 7 中,String
有两个额外的 int
字段).
new Object()
占用 12 个字节的内存(由于对象头等内部事物)。
一个字符串有(括号中的字节数):
- 一个对象头(12),
- 对
char[]
的引用(4 - 假设在 64 位 JVM 中压缩 OOP), int hash
(4)。
那是 20 个字节,但是对象被填充到 8 字节的倍数 => 24。所以这已经是数组实际内容之上的 24 个字节。
char[]
有一个标题 (12)、一个长度 (4) 和每个字符 (10 x 2 = 20) 填充到下一个 8 的倍数 - 或总共 40。
byte[]
有一个 header (12)、一个长度 (4) 和每个字节 (10 x 1 = 10) = 26,填充到下一个 8 的倍数 = 32。
所以我们得到了你的数字。
另请注意,字节数取决于您使用的编码 - 例如,如果您使用 message.getBytes(StandardCharsets.UTF_16)
重试,您将看到字节数组使用 40 个字节共 32 个。
您可以使用 jol可视化内存使用情况并确认上面的计算。 char[]
的输出是:
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) 41 00 00 f8 (01000001 00000000 00000000 11111000) (-134217663)
12 4 (object header) 0a 00 00 00 (00001010 00000000 00000000 00000000) (10)
16 20 char [C.<elements> N/A
36 4 (loss due to the next object alignment)
Instance size: 40 bytes (reported by Instrumentation API)
因此您可以看到 12 的标题(前 3 行)、长度(第 4 行)、字符(第 5 行)和填充(第 6 行)。
与字符串类似(注意这不包括数组本身的大小):
OFFSET SIZE TYPE DESCRIPTION VALUE
0 4 (object header) 01 00 00 00 (00000001 00000000 00000000 00000000) (1)
4 4 (object header) 00 00 00 00 (00000000 00000000 00000000 00000000) (0)
8 4 (object header) da 02 00 f8 (11011010 00000010 00000000 11111000) (-134216998)
12 4 char[] String.value [A, B, C, D, E, F, G, H, I, J]
16 4 int String.hash 0
20 4 (loss due to the next object alignment)
Instance size: 24 bytes (reported by Instrumentation API)
关于java - Java 中字符串表示的不同大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35337565/