欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-04-14 07:51:02
...

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

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

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

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

阿里面试题:一个 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 字符串占多少内存?

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

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

根据上面这个图,我们可以看出 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 工具统计出来,用法和上面的类似。

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

相关标签: Java面试题大全