面试官问我:Object o = new Object() 占用了多少个字节?
小小面试一下
前言蜜语
最近马师傅火的不要不要的,虽然没有抢到耗子尾汁的商标注册权,但是必须得蹭一波马师傅的热度,下面就是闪电五连鞭的教学环节,你准备好了吗!
在正式内容开始前先甩两篇关于类加载机制和内存布局的文章,因为今天的内容多少与这两篇文章有直接的联系,对这方面还比较薄弱的朋友可以先看看,地址我放在下面。
今天本文的内容就针对刚刚模拟面试两个问题
1.对象的创建过程
2.对象的内存布局
对象的创建过程
以下内容基于HotSpot VM 分代模型
这张图其实就能完整的说明一个对象的创建过程到底发生了什么,很多朋友可能一下看不懂,那么我们就跟着左上角的一步一步来:
- 一个对象new出来先判断线程栈是否能分配下
- 如果能分配下,直接分配在栈中。
- 如果分配不下则进行第二步。
- 判断该对象是否足够大
- 如果足够大,则直接进入老年代。
- 如果不够大,则进行第三步。
- 判断创建对象的线程的TLAB(本地线程缓冲区)空间是否足够
- 如果足够,直接分配在TLAB中。
- 如果不够,则进入Eden区中其他空间。然后进行第四步。
- GC清除
- 如果清除掉了该对象,则直接结束。
- 如果没有清除掉对象,进行第5步。
- 此刻对象进入Survivor 1 区,判断年龄是否足够大
- 如果年龄足够大,则直接进入old区域。
- 如果年龄不够大,则进入Survivor 2 区,然后进入第4步,循环往复。
通过这张流程图和步骤解析大家应该对一个对象的创建过程有一个很清晰的概念了,但是其中还是有很多小细节会被忽略,为什么jvm会在对象的创建过程中大作文章,会分这么多种情况?为了让大家更深入的能够理解它,我们就再来看看下面这几个问题:
- 为什么对象会选择先分配在栈中?
首先栈是线程私有的,将对象优先分配在栈中,可以通过pop直接将对象的所有信息,空间直接清除,当线程消亡的时候也可以直接清理这一块儿TLAB区域。
- 为什么jvm会让大对象会直接进入老年代?
大对象需要连续的空间来存储,如果不存入老年代对jvm说就可能是一个负担,如果没有足够的空间就有可能导致提前触发gc来清理空间来安置大对象。
- 为什么会选择先进入TLAB?
TLAB是线程本地缓冲区,TLAB的好处就是防止不同线程创建对象选择同一块儿内存区域而产生竞争,会使其概率大大减少。
- 为什么会有两个Survivor区?并且存活且年龄不够大的对象会从一个Survivor区转到另一个Survivor区?
根据根可达算法,jvm会从开始寻找到所有正在使用的对象,没有使用的就是垃圾,通常情况下,很多对象都是用完就抛弃的,所以真正在Survivor区长时间存活的对象非常少,将这部分对象从一个Survivor区转到另一个Survivor区后,就可以直接对这个Survivor区进行全量的空间回收了,效率会很高。
对象的内存布局
作者可不是标题党,哈哈,所以我们回到文章的标题,Object o = new Object();到底占用多少个字节?这道题的目的其实就是考验看你对对象的内存布局了解的是否清晰,先上图:
在java中对象的内存布局分为两种情况,非数组对象和数组对象,数组对象和非数组对象的区别就是需要额外的空间存储数组的长度length。
对象头
对象头又分为MarkWord和Class Pointer两部分。
MarkWord:包含一系列的标记位,比如轻量级锁的标记位,偏向锁标记位,gc记录信息等等,在32位系统占4字节,在64位系统中占8字节。
ClassPointer:用来指向对象对应的Class对象(其对应的元数据对象)的内存地址。在32位系统占4字节,在64位系统中占8字节。
Length:只在数组对象中存在,用来记录数组的长度,占用4字节
Interface data
- Interface data:对象实际数据,对象实际数据包括了对象的所有成员变量,其大小由各个成员变量的大小决定。(这里不包括静态成员变量,因为其是在方法区维护的)
Padding
- Padding:Java对象占用空间是8字节对齐的,即所有Java对象占用bytes数必须是8的倍数,是因为当我们从磁盘中取一个数据时,不会说我想取一个字节就是一个字节,都是按照一块儿一块儿来取的,这一块大小是8个字节,所以为了完整,padding的作用就是补充字节,保证对象是8字节的整数倍。
moon在上文特意标注了32位系统和64位系统不同区域占用空间大小的区别,这是因为对象指针在64位JVM下的寻址更长,所以想比32位会多出来更多占用空间。
但是现在假设一个场景,公司现在项目部署的机器是32位的,你们老板要让你将项目迁移到64位的系统上,但是又因为64位系统比32位系统要多出更多占用空间,怎么办,因为正常来说我们是不需要这一部分多余空间的,所以jvm已经帮你考虑好了,那就是指针压缩。
指针压缩
-XX:+UseCompressedOops 这个参数就是JVM提供给你的解决方案,可以压缩指针,将占用的空间压缩为原来的一半,起到节约空间的作用,classpointer参数大小就受到其影响。
Object o = new Object()到底占用多少个字节?
通过刚才内存布局的学习后,这个问题就很好回答了,面试官其实就是想问你对象的内存布局是怎样的,我们这里就针对这个问题的结果分析下,这里分两种情况:
在开启指针压缩的情况下,markword占用4字节,classpoint占用8字节,Interface data无数据,总共是12字节,由于对象需要为8的整数倍,Padding会补充4个字节,总共占用16字节的存储空间。
在没有指针的情况下,markword占用8字节,classpoint占用8字节,Interface data无数据,总共是16字节。
结语
今天的文章和大家介绍了一个对象的创建过程,从它的出生到死亡,都经历了什么?也和大家详细的说明了对象的内存布局,深入解剖了一下对象的身体构造,这下面试官再问你,可就有的聊了,这篇文章的内容还是比较肝的,需要大家认真阅读一下,当然,也可以关注我的公众号'哪儿来的moon',私下联系我,我是moon,下期见~
面试官问我:Object o = new Object() 占用了多少个字节?的更多相关文章
- 腾讯面试官问我Java中boolean类型占用多少个字节?我说一个,面试官让我回家等通知
本文首发于微信公众号:程序员乔戈里 什么是boolean类型,根据官方文档的描述: boolean: The boolean data type has only two possible value ...
- 面试官问:JS的this指向
前言 面试官出很多考题,基本都会变着方式来考察this指向,看候选人对JS基础知识是否扎实.读者可以先拉到底部看总结,再谷歌(或各技术平台)搜索几篇类似文章,看笔者写的文章和别人有什么不同(欢迎在评论 ...
- 面试官问你JS基本类型时他想知道什么?
面试的时候我们经常会被问答js的数据类型.大部分情况我们会这样回答包括:1.基本类型(值类型或者原始类型): Number.Boolean.String.NULL.Undefined以及ES6的Sym ...
- 面试官问线程安全的List,看完再也不怕了!
最近在Java技术栈知识星球里面有球友问到了线程安全的 List: 扫码查看答案或加入知识星球 栈长在之前的文章<出场率比较高的一道多线程安全面试题>里面讲过 ArrayList 的不安全 ...
- 美团面试官问我一个字符的String.length()是多少,我说是1,面试官说你回去好好学一下吧
本文首发于微信公众号:程序员乔戈里 public class testT { public static void main(String [] args){ String A = "hi你 ...
- 当面试官问我ArrayList和LinkedList哪个更占空间时,我这么答让他眼前一亮
前言 今天介绍一下Java的两个集合类,ArrayList和LinkedList,这两个集合的知识点几乎可以说面试必问的. 对于这两个集合类,相信大家都不陌生,ArrayList可以说是日常开发中用的 ...
- 「每日一题」有人上次在dy面试,面试官问我:vue数据绑定的实现原理。你说我该如何回答?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 来源:原创 一.前言 文章首发在「松宝写代码」 2020. ...
- [每日一题]面试官问:Async/Await 如何通过同步的方式实现异步?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- [每日一题]面试官问:for in和for of 的区别和原理?
关注「松宝写代码」,精选好文,每日一题 时间永远是自己的 每分每秒也都是为自己的将来铺垫和增值 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
- [每日一题]面试官问:谈谈你对ES6的proxy的理解?
[每日一题]面试官问:谈谈你对ES6的proxy的理解? 关注「松宝写代码」,精选好文,每日一题 作者:saucxs | songEagle 一.前言 2020.12.23 日刚立的 flag,每日一 ...
随机推荐
- 微课制作软件Camtasia中如何添加并编辑字幕?
除了能录制视频以外,Camtasia还能直接把录制下来的视频进行剪辑,并添加视频字幕等等一些后期效果.今天我们就来看一看字幕的添加方法. 导入视频 微课制作软件Camtasia录制的视频,默认在软件& ...
- 清理工具CleanMyMac如何帮助用户清空DNS缓存
什么是DNS缓存?这个缓存有什么危害?相信大家平时使用浏览器时,有时候会遇到一个很奇怪的问题,就是Mac打开许多网站如百度网站,都是可以访问的,但是在打开某个特定网站时,却发现浏览器提示检测不到网络连 ...
- css3系列之text-shadow 浮雕效果,镂空效果,荧光效果,遮罩效果
text-shadow 其实这东西,跟 box-shadow 差不多,没啥好说的不懂的话,点这里→ css3系列之详解box-shadow . 它只有 四个参数 x(第一个值设置x位置) y(第 ...
- Java基础教程——Map
Map 返回类型 方法 描述 V get(Object key) 根据key取得value V put(Obejct k,Object v) 向Map中加入(替换)元素,返回之前的Value:之前没有 ...
- Clickhouse 入门
clickhouse 简介 ck是一个列式存储的数据库,其针对的场景是OLAP.OLAP的特点是: 数据不经常写,即便写也是批量写.不像OLTP是一条一条写 大多数是读请求 查询并发较少,不适合放置先 ...
- unittest框架中读取有特殊符号的配置文件内容的方法-configparser的RawConfigParser类应用
在搭建Unittest框架中,出现了一个问题,配置文件.ini中,出现了特殊字符如何处理? 通过 1.configparser的第三方库对应的ConfigParser类,无法完成对特殊字符的读取: # ...
- 使用react终端运行npm start时报错
npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! my-app@0.1.0 start: `react-scripts start` npm ERR ...
- 大数据开发-Hive-常用日期函数&&日期连续题sql套路
前面是常用日期函数总结,后面是一道连续日期的sql题目及其解法套路. 1.当前日期和时间 select current_timestamp -- 2020-12-05 19:16:29.284 2.获 ...
- 第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解
第8.3节 Python类的__init__方法深入剖析:构造方法与继承详解 一. 引言 上两节介绍了构造方法的语法及参数,说明了构造方法是Python的类创建实例后首先执行的方法,并说明如果类 ...
- PyQt(Python+Qt)学习随笔:QTableView的showGrid属性
老猿Python博文目录 老猿Python博客地址 showGrid属性用于控制视图中数据项之间是否显示网格,如果该属性为True,则绘制网格:如果该属性为False,则不绘制网格. showGrid ...