通过将一个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()));这是使用大面积来测量对象的大小。上述结果表明:
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
发布于 2016-02-11 11:29:15
下面的数据是针对Hotspot / Java 8的--其他JVM/ Java版本的编号将有所不同(例如,在Java7中,String有两个额外的int字段)。
new Object()占用12个字节的内存(由于内部事务,如对象头)。
字符串具有(括号中的字节数):
char[]的引用(4 -假设64位JVM中的压缩OOP ),int hash (4).这是20个字节,但是对象被填充到8字节的倍数中,=> 24。因此,在数组的实际内容之上已经有24个字节了。
char[]有一个头部(12),一个长度(4),每个字符(10x2= 20)被填充到下一个8或40的倍数中。
byte[]有一个头(12),一个长度(4),每个字节(10x1= 10) = 26,填充到下一个倍数8= 32。
这样我们就能找到你的号码了。
还请注意,字节数取决于您使用的编码--例如,如果使用message.getBytes(StandardCharsets.UTF_16)重试,您将看到字节数组使用的是40个字节,而不是32个字节。
您可以使用约尔可视化内存使用情况,并确认上面的计算。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)发布于 2016-02-11 11:12:11
您的每个测试,估计一个Object的大小。在第一种情况下是String对象,第二种是byte数组对象,最后是char数组对象。作为类的实例,每个对象都可能包含一些私有属性和其他类似的东西;因此,您不能期望得到比以下更好的东西:一个10个字符的String至少包含10个字符,每个字符为2个字节,那么整个大小应该是≥20字节,这与您的结果是一致的。
对于字节/字符比较,您错了,因为字符串中的字节数组将为您提供给定编码的所有字节。可能发生的情况是,当前的编码使用了一个字符的多个字节。
您可以查看JVM中的Object、String类和数组支持的Java源代码,以了解到底发生了什么。
https://stackoverflow.com/questions/35337565
复制相似问题