写在前面

对于Java中的String类占用多大的内存空间这个问题,是最近面试中问的比较多的一个问题。很多小伙伴的回答的都不是很正确,有说不占空间的,有说1个字节的,有说2个字节的,有说3个字节的,有说不知道的,更让人哭笑不得的是竟然还有人说是2的31次方。那如果真是这样的话,服务器的内存空间还放不下一个字符串呀!作为程序员的我们,可不能闹这种笑话呀。今天,我们就一起来聊聊Java中的String到底占用多大的内存空间!

Java对象的结构

首先,我们来下Java对象在虚拟机中的结构,这里,以HotSpot虚拟机为例。

注:图片来源http://r6d.cn/wp7q

从上面的这张图里面可以看出,对象在内存中的结构主要包含以下几个部分:Mark Word(标记字段):对象的Mark Word部分占4个字节,其内容是一系列的标记位,比如轻量级锁的标记位,偏向锁标记位等等。

Klass Pointer(Class对象指针):Class对象指针的大小也是4个字节,其指向的位置是对象对应的Class对象(其对应的元数据对象)的内存地址

对象实际数据:这里面包括了对象的所有成员变量,其大小由各个成员变量的大小决定,比如:byte和boolean是1个字节,short和char是2个字节,int和float是4个字节,long和double是8个字节,reference是4个字节

对齐:最后一部分是对齐填充的字节,按8个字节填充。

换种说法就是:对象头(object header):8 个字节(保存对象的 class 信息、ID、在虚拟机中的状态)

Java 原始类型数据:如 int, float, char 等类型的数据

引用(reference):4 个字节

填充符(padding)

Java中的String类型

空String占用的空间

这里,我们以Java8为例进行说明。首先,我们来看看String类中的成员变量。/** The value is used for character storage. */

private final char value[];

/** Cache the hash code for the string */

private int hash; // Default to 0

/** use serialVersionUID from JDK 1.0.2 for interoperability */

private static final long serialVersionUID = -6849794470754667710L;

在 Java 里数组也是对象,因此数组也有对象头。所以,一个数组所占的空间为对象头所占的空间加上数组长度加上数组的引用,即 8 + 4 + 4= 16 字节 。

所以,我们可以得出一个空String对象所占用的内存空间,如下所示。对象头(8 字节)+ 引用 (4 字节 ) + char 数组(16 字节)+ 1个 int(4字节)+ 1个long(8字节)= 40 字节

所以,小伙伴们,你们的回答正确吗?

非空String占用的空间

如果String字符串的长度大于0的话,我们也可以得出String占用内存的计算公式,如下所示。40 + 2 * n

其中,n为字符串的长度。

这里,可能有小伙伴会问,为什么是 40 + 2 n 呢?这是因为40是空字符串占用的内存空间,这个我们上面已经说过了,String类实际上是把数据存储到char[]这个成员变量数组中的,而char[]数组中的一个char类型的数据占用2个字节的空间,所以,只是String中的数据就会占用 2 n(n为字符串的长度)个字节的空间,再加上空字符串所占用的40个字节空间,最终得出一个字符串所占用的存储空间为: 40 + 2 * n (n为字符串长度)。

因此在代码中大量使用String对象时,应考虑内存的实际占用情况。

注:40 + 2 * n 这个公式我们可以看成是计算String对象占用多大内存空间的通用公式。

验证结论

接下来,我们就一起来验证下我们上面的结论。首先,创建一个UUIDUtils类用来生成32位的UUID,如下所示。package io.mykit.binghe.string.test;

import java.util.UUID;

/**

* @author binghe

* @version 1.0.0

* @description 生成没有-的UUID

*/

public class UUIDUtils {

public static String getUUID(){

String uuid = UUID.randomUUID().toString();

return uuid.replace("-", "");

}

}

接下来,创建一个TestString类,在main()方法中创建一个长度为4000000的数组,然后在数组中放满UUID字符串,如下所示。package io.mykit.binghe.string.test;

import java.util.UUID;

/**

* @author binghe

* @version 1.0.0

* @description 测试String占用的内存空间

*/

public class TestString{

public static void main(String[] args){

String[] strContainer = new String[4000000];

for(int i = 0; i < 4000000; i++){

strContainer[i] = UUIDUtils.getUUID();

System.out.println(i);

}

//防止程序退出

while(true){

}

}

}

这里,4000000个字符串,每个字符串的长度为32,所以保存字符串数据所占用的内存空间为:(40 + 32 2) 4000000 = 416000000字节,约等于416MB。

我们使用Jprofiler内存分析工具进行分析:

可以看到,使用Jprofiler内存分析工具的结果为:321MB + 96632KB,约等于417MB。之所以使用Jprofiler内存分析工具得出的结果比我们计算的大些,是因为在程序实际运行的过程中,程序内部也会生成一些字符串,这些字符串也会占用内存空间!!

所以,使用Jprofiler内存分析工具得出的结果符合我们的预期。

好了,今天就到这儿吧,我是冰河,大家有啥问题可以在下方留言,也可以加我微信:sun_shine_lyz,我拉你进群,一起交流技术,一起进阶,一起牛逼~~

java string占用内存_Java中String到底占用多大的内存空间?相关推荐

  1. java中string类相等_Java中String类的常见面试题

    第一题:==与equals()的区别 1.判断定义为String类型的s1和s2是否相等 String s1 = "abc"; String s2 = "abc" ...

  2. java string 对象地址_Java中String对象的存储位置(学习笔记)

    packagetest.string.equal;public classMain {/*** 创建了三个对象,"helloworld对象创建在常量池中",每次new String ...

  3. java valueof的用法_Java中String.valueOf()方法的使用

    Java中String.valueOf()方法的使用 (2013-06-21 18:07:34) 标签: it Java中String.valueOf() 方法的使用 1. 由 基本数据型态转换成 S ...

  4. Java吃CPU还是内存_Java中的CPU占用高和内存占用高的问题排查

    下面通过模拟实例分析排查Java应用程序CPU和内存占用过高的过程.如果是Java面试,这2个问题在面试过程中出现的概率很高,所以我打算在这里好好总结一下. 1.Java CPU过高的问题排查 举个例 ...

  5. java如何接受字符_java中string怎么获取指定位置的字符

    //截取#之前的字符串String str = "sdfs#d";str.substring(0, str.indexOf("#"));// 输出的结果为:sd ...

  6. java里面string什么意思_java中string什么意思

    详细内容 Java是面向对象的编程语言,它其中包含有各种各样的名词,都有着不同的意思.Java中的string是字符串的意思,当声明了一个字符串变量时,便可以在里面存储数据. 一.String类 想要 ...

  7. java中string的方法_java中String类中的常用方法

    @Test public void testToString2() {  /**   * 他会调用toString方法 他调用的其实是Object类中的toString方法 引用会隐式调用toStri ...

  8. java中string的方法_java中String的常用方法

    package com.string; public class string1 { public static void main(String args[]){ //将char[]数组转换成Str ...

  9. java char字节数_Java中char到底是多少字节?

    展开全部 java中的char占62616964757a686964616fe58685e5aeb9313333376234342个字节 1:"字节"是byte,"位&q ...

最新文章

  1. 阿里安全新研究:给图片打“马赛克”就能骗过 AI 视觉系统
  2. Android_图像渲染(Shader)
  3. Alcatel 6850实现静态路由
  4. 自定义控件-条状、块状菜单
  5. AlertView动画
  6. linux pstree乱码,pstree下显示乱码解决
  7. 移动支付批量制卡系统架构
  8. try、catch、finally用法总结
  9. Oracle 之 管理
  10. python函数结构_PYTHON 之结构体,全局变量,函数参数,lambda编程 等
  11. perl语言学习笔记(3)列表与数组、子程序’、参数
  12. 【实习记】2014-09-26恢复linux下误删的ntfs盘中的文件
  13. linux防火墙的策略规则
  14. 百度实习1,2,3面-教育知心搜索前端项目组
  15. 关于FbinstTool加入360急救盘见解
  16. 手把手带你可视化分析NBA首轮球队表现及火勇对决前瞻!
  17. ir2113错误电路
  18. 如何在计算机中打开显卡,windows系统如何打开显卡的硬件加速呢?
  19. android 换行符 编码_android中的常见的占位符及转义字符
  20. 显卡超频很简单 RivaTuner使用教程

热门文章

  1. 双向广搜-HDU1401 Solitaire
  2. win10查看电脑开机时长
  3. 企业邮箱群发邮件 - 邮件群组群发邮件详解
  4. 历史在重演:从KHTML到WebKit,再到Blink
  5. 【iOS】录音和音频合成
  6. 基于SSM的汽车维修管理软件设计与实现
  7. U盘安装kali linux
  8. 用python批量修改图片名称!超级简单
  9. 100万量子比特,PsiQuantum要怎样实现?
  10. 软件设计师中级复习小总结