阿里面试题:一个 String 字符串占多少内存?

本文探讨了在面试中遇到的关于Java中String对象内存占用的问题。通过分析,指出一个空String在JDK 6和JDK 8中分别占用40字节和32字节,并提供了计算String内存的公式。文章建议理解和使用Java的jol-core工具进行内存计算。
摘要由CSDN通过智能技术生成

最近一个网友问我,在面试阿里的时候,被问到了一个 String 字符串占用多少内存的问题?他当时懵了,因为他只记得基本数据类型占用的空间大小。

说实话,这个问题,如果是我,我也可以会回答错误。

网上曾经有一道非常著名的题,如下:

既然选项是字节,那我们就应该这么算。

String str = "搞java";  
System.out.println("\"搞java\".length():" + (str.length()));  
System.out.println("\"搞java\".getBytes().length:" + (str.getBytes().length));  
System.out.println("\"搞java\".getBytes(\"GBK\").length:" + (str.getBytes("GBK").length));  
System.out.println("\"搞java\".getBytes(\"UTF-8\").length:" + (str.getBytes("UTF-8").length));  
/**
"搞java".length():5
"搞java".getBytes().length:6
"搞java".getBytes("GBK").length:6
"搞java".getBytes("UTF-8").length:7
*/

所以,选 A 或选 B 都说得过去。但是这是一个单选题,官方给出的最终正确答案是 A,即 6 个字节。原因是,我们的 Window 系统,默认的是 GBK,所以,答案为 A。

现在我们回归到的主题,一个 String 字符串占多少内存?就如上面这个选择题一样,看起来比 long 和 double 都要节约空间?

搜寻了好久,国外网友给出了一个计算公式:

这个公式看的我糊里糊涂的,我们看看 String 的源码。里面有一个 int 的 hash,还有一个 char [] 数组。所以,单纯的讲上面的字符串占用的空间肯定不止 6 个字节。

根据上面这个图,我们可以看出 String 对象的一个基本内存布局情况。需要注意的是 JDK 6 和 JDK 8 String 对象有所改动,计算方式不一样。

由上图可知,一个空 String 所占空间为:

对象头(8 字节)+ char 数组(16 字节)+ 3 个 int(3 × 4 = 12 字节)+1 个 char 数组的引用 (4 字节 ) = 40 字节。这里是 JDK 6 的计算方法。

JDK 8 中,只有一个 int 了,所以一个空的 String 占用 32 字节。

所以,我们最终可以总结一个公式:

// JDK 6
8*( ( 8+2*n+4+12)+7 ) / 8 = 8*(int) ( ( ( (n) *2 )+43) /8 )
// JDK 8
8*( ( 8+2*n+4+4)+7 ) / 8 = 8*(int) ( ( ( (n) *2 )+43) /8 )

其中 N 为字符串长度。

那个这个题,该怎么回答呢?说出你的思路,你对 String 内部结构的构成理解,和计算方式就可以了。实在记不住,也可以使用 Java 自带的 jol-core 工具来计算。

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

引入上面的 pom 配置,然后编写简单的几行代码就可以计算出来。

public class XttblogObjectMemory {
    public static void main(String[] args) {
        System.out.print(ClassLayout.parseClass(String.class)
            .toPrintable());
    }
}

空字符串的内存占用情况,计算结果如下所示:

java.lang.String object internals:
     OFFSET  SIZE     TYPE DESCRIPTION                   VALUE     
     0      12          (object header)                  N/A     
     12     4   char[] String.value                      N/A     
     16     4      int String.hash                       N/A
     20     4          (loss due to the next object alignment)
Instance size: 24 bytes

其他 Java 类的内存占用情况,也可以通过 jol-core 工具统计出来,用法和上面的类似。

以上,你知道的越多,不知道的就越多,业余的像一棵小草一样。

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业余草

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值