首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中不同大小的字符串表示

Java中不同大小的字符串表示
EN

Stack Overflow用户
提问于 2016-02-11 11:03:19
回答 2查看 255关注 0票数 9

通过将一个String分解成其组成部分,我比较了在java中存储String的各种方法。我有下面的代码片段:

代码语言:javascript
复制
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()));

这是使用大面积来测量对象的大小。上述结果表明:

代码语言:javascript
复制
As String 64 bytes
As byte[] 32 bytes
As char[] 40 bytes

假设一个byte是8位,char是16位,为什么结果不是分别是10字节和20字节?

此外,导致String对象的开销是基础byte[]的两倍。

这是用

代码语言:javascript
复制
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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-02-11 11:29:15

下面的数据是针对Hotspot / Java 8的--其他JVM/ Java版本的编号将有所不同(例如,在Java7中,String有两个额外的int字段)。

new Object()占用12个字节的内存(由于内部事务,如对象头)。

字符串具有(括号中的字节数):

  • 对象标头(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[]的输出是:

代码语言:javascript
复制
 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行)。

类似地,对于字符串(注意,这不包括数组本身的大小):

代码语言:javascript
复制
 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)
票数 6
EN

Stack Overflow用户

发布于 2016-02-11 11:12:11

您的每个测试,估计一个Object的大小。在第一种情况下是String对象,第二种是byte数组对象,最后是char数组对象。作为类的实例,每个对象都可能包含一些私有属性和其他类似的东西;因此,您不能期望得到比以下更好的东西:一个10个字符的String至少包含10个字符,每个字符为2个字节,那么整个大小应该是≥20字节,这与您的结果是一致的。

对于字节/字符比较,您错了,因为字符串中的字节数组将为您提供给定编码的所有字节。可能发生的情况是,当前的编码使用了一个字符的多个字节。

您可以查看JVM中的ObjectString类和数组支持的Java源代码,以了解到底发生了什么。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35337565

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档