面试官:Object o = new Object() 占用了多少字节?
作者 | 哪儿来的moon 责编 | 张文
头图 | CSDN 下载自视觉中国
来源 | 哪儿来的moon(ID:onetraveller_llxz)
面试的时候,要是面试官问了标题那种问题,你知道怎么解答吗?
本文内容将针对以上面试问题做出解答。
对象的创建过程
以下内容基于 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 占用 8 字节,classpoint 占用 4 字节,Interface data 无数据,总共是12字节,由于对象需要为8的整数倍,Padding 会补充4个字节,总共占用16字节的存储空间。
在没有指针压缩的情况下,markword 占用 8 字节,classpoint 占用 8字节,Interface data 无数据,总共是16字节。
了解了对象的创建过程和对象的内存布局,Object o = new Object() 占用了多少字节?这类问题就不是难事了!
更多精彩推荐
☞告别 Windows、Android,国产操作系统合力破局 ☞开源吞噬世界,得开发者得天下 ☞小米 11 发布,售价 3999 元起;罗永浩回应败诉半导体公司;deepin 20.1(1010) 发布|极客头条☞苹果 M1 芯片预示着 RISC-V 完全替代 ARM?
☞5G与金融行业融合应用的场景探索
☞带你一文看懂 Blockchain + NoSQL数据库
点分享点点赞点在看
面试官:Object o = new Object() 占用了多少字节?相关推荐
- 腾讯面试,面试官第一个问题是Int占多少字节,程序员不知所措
在一般的互联网公司的技术人员的面试中,大概会经历3到4轮的面试,差不多2-3轮的技术面,还有1轮的HR面试,有人面试题是有关"目标",有的关于"方法",有的关于 ...
- 阿里面试官太暖了!3技术面+2交叉面+1代码面+1HR面,offer已拿
背景介绍:项目是管理系统,本科211(非科班),硕士985(非科班). 我面试的岗位:java工程师 部门:新零售事业群-业务平台事业部-交易流程组 非常感谢阿里给的机会,感谢遇到的每一位面试官,面试 ...
- smallint占用几个字节_面试官问我:Object o = new Object() 占用了多少个字节?
正文约: 2900字 预计阅读时间: 8分钟 文章首发于我的微信公众号:moon聊技术,欢迎大家关注 moon不讲武德!!!一个类加载机制给面试官说蒙了!! 小小面试一下 前言蜜语 最近马师傅火的不要 ...
- 面试官欺负人:new Object()到底占用几个字节?
前言 我们来分析一下堆内布局以及Java对象在内存中的布局吧. 对象的指向 先来看一段代码: package com.zwx.jvm;public class HeapMemory {private ...
- 聚通达科技java面试_面试官就这么欺负人:new Object()到底占用几个字节?
本文同名博客老炮说Java:https://www.laopaojava.com/,每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料 背景 前言 现在就让我们继续来分 ...
- obj: object是什么意思_面试官问你JavaScript基本类型时他想知道什么?
本文原载于SegmentFault专栏"前端小将" 整理编辑:SegmentFault 面试的时候我们经常会被问答js的数据类型.大部分情况我们会这样回答包括: 1.基本类型(值类 ...
- 面试官问:数据库 delete 表数据,磁盘空间还是被一直占用,为什么?
以下文章来源方志朋的博客,回复"666"获面试宝典 最近有个上位机获取下位机上报数据的项目,由于上报频率比较频繁且数据量大,导致数据增长过快,磁盘占用多. 为了节约成本,定期进行数 ...
- 面试官上来就问:Java 进程中有哪些组件会占用内存?
本文的内容来自 StackOverflow 的一个问答:Java using much more memory than heap size (or size correctly Docker mem ...
- 【Redis系列】面试官:Redis中的数据已经过期,为什么还占用这内存?
如果有面试官问Redis中的数据已经过期为什么还占用这内存? 它是因为Redis本身的过期策略和缓存淘汰机制所导致的. 说说Redis的过期策略和缓存淘汰机制 先来说说Redis的过期策略,Redis ...
最新文章
- zuul filter
- java after方法_spring AOP的After增强实现方法实例分析
- pytorch torch.Tensor.clone()(返回张量自身的副本。 副本具有与自身相同的大小和数据类型。)
- 【weex开发】环境配置流程
- 深入浅出计算机组成原理01:计算机概要与技术
- Python之Pandas库常用函数大全(含注释)
- python中静态方法、类方法、属性方法区别
- Spring集成quartz实现的定时任务调用
- Excel表格中的删除操作,看看你会几种?
- windows下管理员用户与标准用户切换过程中的坑
- Ros同一局域网下多机通信
- 中国电信“公板”计划主攻中端市场
- TexStudio论文写作小白入门
- 基于Java的Minecraft游戏后端自定义插件 05事件监听器
- JavaFXでJava RIA開発はどれくらい変わるの?
- 关于电脑磁盘消失的解决方法
- Unity中用Shader实现镜子效果
- 12月18日第壹简报,星期日,农历十一月廿五
- 工作随笔:如何开展测试工作
- Java环境的下载和配置
热门文章
- 【英语】Flying By Dream---English
- [ZJOI2007]仓库建设
- JavaScript面向对象实现
- UIWebView 真机iOS 8.x系统上报错
- GC之详解CMS收集过程和日志分析
- Windows Phone开发(40):漫谈关键帧动画之中篇 转:http://blog.csdn.net/tcjiaan/article/details/7559978...
- 提高.net网站的性能
- opensuse ati 显卡驱动安装
- 在Windows 10中使用TortoiseGit进程gitlab仓库的管理
- YellowBrick-聚类评估示例