java string 内存占用_关于java:JVM系列之String数组和集合类的内存占用大小

简介

之前的文章中,咱们应用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. 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在内存中的应用状况。

前面的几个汇合我就没有一一计算,有趣味的敌人能够在下方回复你计算的后果哟。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jvm-collections-size/

本文起源:flydean的博客

欢送关注我的公众号:程序那些事,更多精彩等着您!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值