JVM系列之:String,数组和集合类的内存占用大小

24 篇文章 9 订阅
订阅专栏

目录

 

简介

之前的文章中,我们使用JOL工具简单的分析过String,数组和集合类的内存占用情况,这里再做一次更详细的分析和介绍,希望大家后面再遇到OOM问题的时候不再抱头痛哭,而是可以有章可循,开始吧。

数组

先看下JOL的代码和输出:

//byte array
log.info("{}",ClassLayout.parseInstance("www.flydean.com".getBytes()).toPrintable());

输出结果:

INFO com.flydean.CollectionSize - [B object internals:
 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)                           22 13 07 00 (00100010 00010011 00000111 00000000) (463650)
     12     4        (object header)                           0f 00 00 00 (00001111 00000000 00000000 00000000) (15)
     16    15   byte [B.<elements>                             N/A
     31     1        (loss due to the next object alignment)
Instance size: 32 bytes
Space losses: 0 bytes internal + 1 bytes external = 1 bytes total

注意,本文的结论都在64位的JVM中运行得出了,并且开启了COOPs压缩对象指针技术。

可以看到数组对象的对象头大小是16字节,再加上数组里面的内容长度是15字节,再加上1位补全。最后得到的大小是32字节。

同样的,我们计算存有100个对象的数组,可以得到下面的结论:

注意最后面的Object数组,如果数组中存储的不是基础类型,那么实际上存储的是执行该对象的指针,该指针大小是4个字节。

String

String是一个非常特殊的对象,它的底层是以byte数组存储的。

注意,在JDK9之前,String的底层存储结构是char[],一个char需要占用两个字节的存储单位。

因为大部分的String都是以Latin-1字符编码来表示的,只需要一个字节存储就够了,两个字节完全是浪费。

于是在JDK9之后,字符串的底层存储变成了byte[]。

同样的我们还是用JOL来分析:

//String
log.info("{}",ClassLayout.parseInstance("www.flydean.com").toPrintable());

输出结果:

INFO com.flydean.CollectionSize - java.lang.String object internals:
 OFFSET  SIZE      TYPE DESCRIPTION                               VALUE
      0     4           (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
      4     4           (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4           (object header)                           77 1a 06 00 (01110111 00011010 00000110 00000000) (399991)
     12     4    byte[] String.value                              [119, 119, 119, 46, 102, 108, 121, 100, 101, 97, 110, 46, 99, 111, 109]
     16     4       int String.hash                               0
     20     1      byte String.coder                              0
     21     1   boolean String.hashIsZero                         false
     22     2           (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 2 bytes external = 2 bytes total

可以看到String中的对象头是12字节,然后加上4字节的指针指向一个byte数组。再加上hash,coder,和hasIsZero属性,最后的大小是24字节。

我这里使用的是JDK14的String版本,不同的版本可能有所不同。

当然这只是这个String对象的大小,不包含底层数组的大小。

我们来计算一下String对象的真实大小:

String对象的大小+byte数组的大小=24+32=56字节。

ArrayList

我们构建一个非常简单的ArrayList:

//Array List
log.info("{}",ClassLayout.parseInstance(new ArrayList()).toPrintable());

输出结果:

INFO com.flydean.CollectionSize - java.util.ArrayList object internals:
 OFFSET  SIZE                 TYPE DESCRIPTION                               VALUE
      0     4                      (object header)                           05 00 00 00 (00000101 00000000 00000000 00000000) (5)
      4     4                      (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4                      (object header)                           87 81 05 00 (10000111 10000001 00000101 00000000) (360839)
     12     4                  int AbstractList.modCount                     0
     16     4                  int ArrayList.size                            0
     20     4   java.lang.Object[] ArrayList.elementData                     []
Instance size: 24 bytes
Space losses: 0 bytes internal + 0 bytes external = 0 bytes total

画个图来直观的表示:

这里modCount和size的初始值都是0。

HashMap

因为文章篇幅的限制,这里就不把代码列出来了,我只贴个图上来:

HashSet

LinkedList

treeMap

来个比较复杂的TreeMap:

总结

本文用图形的形式形象的展示了集合对象,数组和String在内存中的使用情况。

后面的几个集合我就没有一一计算,有兴趣的朋友可以在下方回复你计算的结果哟。

Java中StringStringBuffer和StringBuilder的区别和堆栈内存分配
Andyの笔记
11-25 9905
Java中的String类是一个很常用,但最不注意其细节的类,因此大多数面试会那这个类做文章。比如String str = new String("hello");开辟了几个内存空间,StringStringBuffer的区别等等。下面就做一个我的理解: String是一个被final修饰的类,它是不能被继承的。StringBuffer也是被final修饰的类。 一、JVM内存划分 在java中主要存在4块内存,这些内存空间分别为:栈内存空间、堆内存空间、全局数据区、全局代码区 也可以这么说:所
java offer收割指南
10-26
其中,byte 占用 1 字节,short 占用 2 字节,int 占用 4 字节,long 占用 8 字节,float 占用 4 字节,double 占用 8 字节,boolean 占用 1 位,char 占用 2 字节。 2. String 类能被继承吗,为什么? String 类不...
JVM系列之String.intern的性能解析
08-19
主要介绍了JVM系列之String.intern的性能解析,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
随笔:StringStringBuffer的区别
m0_61809764的博客
03-01 47
StringString是一个不可变对象,每次修改String的值都会创建一个新的对象,然后把新的值保存进去;特别是字符串拼接的场景,尤其是循环拼接,会多次创建很少使用的字符串对象,导致有限的内存空间被占用,并且无用的对象过多后还会触发GC,这个过程也会耗费性能。 StringBuffer: StringBuffer是一个可变对象,对StringBuffer的拼接操作的都是同一个对象,不会占用额外空间,适合多字符串拼接的场景。 总结: String不可变,多字符串拼接效率低; Strin
测试String, StringBuffer, StringBuilder的拼接速度, 内存使用情况比较.
非攻的博客
06-25 431
测试采用随机数拼接, 指定数量的随机数初始化的list进行循环顺序拼接. 详细代码在test中. 图中分别是 1万和100万的测试数据. 100w的测试中没使用字符串拼接, 太慢了. 在比较中发现StringBuffer会比StringBuilder多近一倍的内存占用. 原因是因为StringBuffer在对象实例内会存有toString的缓存, 详情参考bufferInfo.txt文件第八...
Java中String字符串拼接和StringBuilder、StringBuffer拼接占用内存的区别和效率
m566666的博客
11-08 1902
public class Teststring { public static void main(String[] args) { String str=new String("000"); long start=System.currentTimeMillis(); for(int i=0;i<10000;i++) { str+="第"+i; } long end=System.currentTimeMillis(); long s=end-start...
String,StringBuffer,StringBuilder效率与内存占用比较
android开发笔记
07-21 1699
分别使用StringStringBuffer,StringBuilder进行10000次的字符串拼接操作,计算运行时间以及java程序运行时的内存占用。 public class StringWasteMemoryTest { public static void main(String[] args) { long beforeTime = System.curre...
redis
xunboang0059的博客
09-16 272
redis 数据类型 string Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,内部为当前字 符串实际分配的空间 capacity 一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,为了避免加倍后的冗余空间过大而导致浪费,所以扩容时一次只会多扩1M...
字符串和数组的区别,长度、所占空间计算和比较
qq_44423388的博客
06-11 3632
char str1[10]={"helllo"}; char str2[10]={'h','e','l','l','o'}; char str3[]={"hello"}; char str4[]={'h','e','l','l','o'}; printf("sizeof(str1):%d strlen(str1):%d\n",sizeof(str1),strlen(str1)); printf("sizeof(str2):%d strlen(str2):%d\n",sizeof(.
C语言数据类型及其大小计算
chaochao_yq的博客
07-23 5155
一、数据类型 C语言数据类型多种多样,常见的数据类型包括: 字符型 char; 短整型 short; 整型 int; 长整型 long; 更长整型 long long; 单精度浮点型 float; 双精度浮点型 double; 其中字符型数据类型用来存放字符,例如a、b、C、D……整型则用来存放整数,浮点型用来存放小数,存在这么多数据类型主要是为了让存储空间利用率更高,更加丰富的表述生活中的各种值。 二、数据类型的大小 每种数据类型在计算机中...
java中各种类型所占内存空间大小
分享+记录
03-09 3772
java中,一些常见类型在虚拟机中所占内存的详细介绍,并且有相关实验进行证明。
2024高级中级-java面试题.docx
最新发布
01-30
每种类型都有其特定的内存占用大小和默认值。例如,整型的默认值为 0,布尔型的默认值为 false,等等。 2. 封装、继承和多态 Java 中的封装是指将对象的状态和行为封装在一个单元中,使其对外部不可见。继承是指一...
Java高级面试题.doc
02-13
可以让老年代尽量缓存常用对象,JVM 默认年轻代和老年代的大小比例为 1:2,可以观察峰值老年代内存,不影响 full GC,加大老年代可调 1:1,但是要给老年代预留三分之一的空间。 4. 字节流和字符流: 字节流不会...
黑马程序员Javase笔记
01-18
增强for循环(也称为foreach循环)简化了对集合的遍历,而`Collections`类提供了许多对集合操作的静态方法,例如排序和过滤。 最后,关于泛型,它们允许在类、接口和方法中定义类型参数,提高了代码的复用性和安全...
Java基础高频的面试题,看这一篇就够了
02-22
Java基础高频面试题总结 一、Java基础知识点 ...本文总结了Java基础高频面试题,包括基本数据类型、接口和抽象类、集合框架、final、finalize和finally、==和equals、StringStringBuffer和StringBuilder等知识点。
StringStringBuffer效率的比较
chj97的专栏
10-24 1782
String str = “”;  for (int i=0; i str += “a”;    可是你知道在内存中会产生多少的垃圾出来吗?总共会有a、aa、aaa、  aaa….,无疑的,上述的程序虽然简单,但浪费了不少的内存,而且产  生对象和对象的存取也会花掉不少的时间,我们加上几行程序代码来测试所  花的时间和内存:  long startTime = System.cur
C# List<string>和string[]区别
Blue
06-30 1295
C# List和string[]区别
Java下得到ArrayList<String>占用内存大小的方法
code_while的博客
04-30 8154
刚需:压测时需要占用较大的内存,但使用ArrayList<String>时,无法获得每次调用占用内存大小. 问题:Java中List的实际申请长度并不是size()取到的长度,而且,每次String申请的内存地址空间和主机有关,诸多因素导致计算估值并不是很准确 参考方案如下 代码 Runtime r = Runtime.getRuntime(); long startRAM...
JVM 系列一:Native memory allocation 导致JVM Crash
05-19
JVM在执行过程中会为Java程序分配一定的内存空间,这些内存空间是属于JVM的堆外内存,也称为直接内存。 当Java程序使用的直接内存超过了JVM指定的最大直接内存限制时,就会出现Native memory allocation导致的JVM ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • TreeMap原理实现及常用方法 29815
  • Activiti工作流的详细介绍 22921
  • 阿里开源!集成了 AIGC 的免费数据库工具:Chat2DB 11566
  • Pycharm第三方库的安装及使用方法 8667
  • layui验证select下拉框不能为空 7205

分类专栏

  • java 24篇
  • 数据结构 2篇
  • android 1篇
  • python 5篇
  • 递归查询 2篇
  • layer 1篇
  • layui 1篇
  • js 10篇
  • 多线程 2篇
  • mysql 2篇
  • sql 3篇
  • jquery 3篇
  • 动漫
  • idea 1篇
  • Google插件
  • echarts 1篇
  • springboot 1篇
  • oracle 1篇
  • list转数组 1篇
  • math 1篇
  • layui图标 1篇
  • 算法 2篇
  • layui表格 1篇
  • 节点 1篇

最新评论

  • 基于ChatGPT的安卓端语音助手

    qq_45530726: 有什么开源可用的对应功能的项目?

  • 基于ChatGPT的安卓端语音助手

    qq_45530726: 博主,ai 传过的 一段段的字符或者字符串怎么动态显示在界面

  • 基于 SpringBoot + Vue 的智能停车场项目。

    weixin_57533039: 有些代码看不懂,能否咨询一下您

  • 2.3k star,一整套完整的 AI 助手系统开源了,逼格拉满、开箱即用,支持一键部署

    CSDN-Ada助手: Python入门 技能树或许可以帮到你:https://edu.csdn.net/skill/python?utm_source=AI_act_python

  • [开源]研发管理项目,支持从需求到代码发布全过程全生命周期管理

    only_youlix: 怎么运行起来啊,哪里有说明

您愿意向朋友推荐“博客详情页”吗?

  • 强烈不推荐
  • 不推荐
  • 一般般
  • 推荐
  • 强烈推荐
提交

最新文章

  • MoneyPrinterTurbo:一键生成短视频的AI神器
  • Python打造的智能家居神器:Home Assistant
  • 基于SpringBoot2.x、SpringCloud和SpringCloudAlibaba并采用前后端分离的企业级微服务多租户系统架构
2024年12篇
2023年108篇
2022年3篇
2021年17篇
2020年48篇
2019年17篇
2018年5篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

TNT报社

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

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

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

打赏作者

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

抵扣说明:

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

余额充值

深圳SEO优化公司坪地网站关键词优化哪家好焦作模板网站建设陇南seo排名公司承德seo优化价格济宁SEO按效果付费公司湖州网站优化按天扣费价格韶关关键词按天计费推荐马鞍山网站优化软件哪家好鹤岗网站搜索优化价格淮安网站搜索优化多少钱衡阳营销型网站建设多少钱来宾网站seo优化多少钱湘潭百度关键词包年推广六安百度竞价价格商洛百度网站优化排名哪家好娄底SEO按天扣费报价镇江百度seo绵阳推广网站推荐飞来峡网站优化按天收费哪家好金昌网站推广方案多少钱韶关如何制作网站木棉湾营销型网站建设珠海百度seo德州关键词排名推荐三亚seo优化报价承德英文网站建设海西企业网站建设公司海南seo网站推广公司荆门优化推荐百色营销网站推荐歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化