美团应届生面试第一问:Object o = new Object()占用多少字节?

news2024/11/26 0:49:25

文章目录

    • 工具查看内存分配
    • Java内存模型
    • 访问对象方式
    • GC
      • 为什么Survivor要分为两个区域(S0和S1)?
      • Survivor 为什么不分更多块呢?
    • 对象的生命周期
    • 小知识

工具查看内存分配

Object o = new Object();占用多少字节,我们借助openjdk的工具来看一下:

Maven依赖

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.10</version>
</dependency>

代码:

package com.ossa.issavior.sle;

import org.openjdk.jol.info.ClassLayout;

public class TestController {

    public static void main(String[] args){
        Object o = new Object();

        // 类的大小
        ClassLayout classLayout = ClassLayout.parseClass(o.getClass());
        System.out.println(classLayout);

        // 实例大小的布局
        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}

在这里插入图片描述

Java内存模型

可以看到new Object()占用16个字节,我们来看一下Java内存模型。
在这里插入图片描述
jvm默认是开启了指针压缩:

-XX:+UseCompressedOops  开启指针压缩
-XX:-UseCompressedOops  关闭指针压缩

压缩之后类型指针只占4个字节,否则占用8个字节。

访问对象方式

创建好一个对象之后,访问对象方式有两种:句柄访问和直接指针访问。

句柄访问:使用句柄访问的话,Java虚拟机会在堆内划分出一块内存来存储句柄池,那么对象当中存储的就是句柄地址,然后句柄池中才会存储对象实例数据和对象类型数据地址。
在这里插入图片描述
直接指针访问(Hot Spot虚拟机采用的方式): 直接指针访问的话对象中就会直接存储对象类型数据。
在这里插入图片描述
上面图形中我们很容易对比,就是如果使用句柄访问的时候,会多了一次指针定位,但是他也有一个好处就是,假如一个对象被移动(地址改变了),那么只需要改变句柄池的指向就可以了,不需要修改reference对象内的指向,而如果使用直接指针访问,就还需要到局部变量表内修改reference指向。

GC

在Java对象头当中的Mark Word存储了对象的分代年龄,那么什么是分代年龄呢?

一个对象的分代年龄可以理解为垃圾回收次数,当一个对象经过一次垃圾回收之后还存在,那么分代年龄就会加1,在64位的虚拟机中,分代年龄占了4位,最大值为15。分代年龄默认为0000,随着垃圾回收次数,会逐渐递增。

Java堆内存中按照分代年龄来划分,分为Young区和Old区,对象分配首先会到Young区,达到一定分代年龄(-XX:MaxTenuringThreshold可以设置大小,默认为15)就会进入Old区(注意:如果一个对象太大,那么就会直接进入Old区)。

再把Young区再次划分一下,分为2个区:Eden区和Survivor区。

最后把Survivor区给一分为二。

在这里插入图片描述
这个时候工作流程又变成这样了: 首先还是在Eden区分配空间,Eden区满了之后触发GC,GC之后把幸存对象 复制到S0区(S1区是空的),然后继续在Eden区分配对象,再次触发GC之后如果发现S0区放不下了(产生空间碎片,实际还有空间),那么就把S0区对象复制到S1区,并把幸存对象也复制到S1区,这时候S0区是空的了,并依次反复操作,假如说S0区或者S1区空间对象复制移动了之后还是放不下,那就说明这时候是真的满了,那就去老年区借点空间过来(这就是担保机制,老年代需要提供这种空间分配担保),假如说老年区空间也不够了,那就会触发Full GC,如果还是不够,那就会抛出OutOfMemeoyError异常了。

注意:为了确保S0和S1两个区域之间每次复制都能顺利进行,S0和S1两个区的大小必须要保持一致,而且同一时间有一个区域一定是空的。虽然说这种做法是会导致了一小部分空间的浪费,但是综合其他性能的提升来说,是值得的。

当Young区的对象达到设置的分代年龄之后,对象会进入Old区,Old区满了之后会触发Full GC,如果还是清理不掉空间,那么就抛出OutOfMemeoyError异常。

这里还存在两个问题:

为什么Survivor要分为两个区域(S0和S1)?

设置两个 Survivor 区最大的好处就是解决内存碎片化。

假设一下,Survivor 如果只有一个区域会怎样?

刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。这样继续循环下去,下一次Eden满了的时候,问题来了,如果采用复制算法:Survivor区域很容易就满了,会频繁Minor GC;如果是标记清除,在新生代这种经常会消亡的区域,采用标记清除必然会让内存产生严重的碎片化。

如果Survivor 有2个区域,所以每次 Minor GC,会将之前 Eden 区和 From 区中的存活对象复制到 To 区域。第二次 Minor GC 时,From 与 To 职责兑换,这时候会将 Eden 区和 To 区中的存活对象再复制到 From 区域,以此反复。这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生。

Survivor 为什么不分更多块呢?

这种机制最大的好处就是,整个过程中,永远有一个 Survivor space 是空的,另一个非空的 Survivor space 是无碎片的。

那么,Survivor 为什么不分更多块呢?比方说分成三个、四个、五个?显然,如果 Survivor 区再细分下去,每一块的空间就会比较小,容易导致 Survivor 区满,两块 Survivor 区可能是经过权衡之后的最佳方案。

对象的生命周期

一个对象会在Eden区,S0区,S1区,Old区不断流转(当然,一开始就会被回收的短命对象除外),我们可以得到下面的一个流程图:
在这里插入图片描述

小知识


垃圾回收:简称GC。

Minor GC:针对新生代的GC

Major GC:针对老年代的GC,一般老年代触发GC的同时也会触发Minor GC,也就等于触发了Full GC。

Full GC:新生代+老年代同时发生GC。

Young区:新生代

Old区:老年代

Eden区:暂时没发现有什么中文翻译(伊甸园?)

Surcivor区:幸存区

S0和S1:也称之为from区和to区,注意from和to两个区是不断互换身份的,且S0和S1一定要相等,并且保证一块区域是空的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/42772.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

重要公告 | 论坛域名更换,请务必及时收藏

论坛的小伙伴们&#xff1a; 为进一步规范网站域名&#xff0c;自2022年11月16日起&#xff0c;“西门子低代码开发者论坛”的域名由&#xff1a;https://forum.mendix.tencent-cloud.com/&#xff0c;正式变更为&#xff1a;https://marketplace.siemens.com.cn/low-code-com…

Kamiya丨Kamiya艾美捷人和动物LBP ELISA说明书

Kamiya艾美捷人和动物LBP ELISA预期用途&#xff1a; 人和动物LBP ELISA已被开发用于定量测定天然和血清&#xff0c;血浆和培养基中的重组人LBP。也适用于牛&#xff0c;猪&#xff0c;兔和狗LBP。仅供研究使用。不用于诊断程序。 Kamiya艾美捷人和动物LBP ELISA原理&#xf…

地理计算 | 计算两个坐标点射线的交点(前方交会)

1 前言 前方交会--- 又称为测角交会&#xff0c;是指从相邻两个已知点向待定点观测两个水平角&#xff0c;用以计算待定点的坐标。 如图所示&#xff0c;点 A、B 的坐标已知。 通过观测角 A 和角 B 求出点 P 坐标的定位方法被称之为“角度前方交会”&#xff1b; 通过观测方…

汽车租赁系统毕业设计,汽车租赁管理系统设计与实现,毕业设计论文毕设作品参考

功能清单 【后台管理员功能】 广告管理&#xff1a;设置小程序首页轮播图广告和链接 留言列表&#xff1a;所有用户留言信息列表&#xff0c;支持删除 会员列表&#xff1a;查看所有注册会员信息&#xff0c;支持删除 资讯分类&#xff1a;录入、修改、查看、删除资讯分类 录入…

代码随想录训练营day46, 单词拆分和多重背包

今天就这一道题, 但还是有难度的 单词就是物品, 字符串s就是背包, 单词能否组成字符串s, 就是问物品能不能把背包装满 确定dp数组含义: 字符串长度为i的话, dp[i]为true, 表示可以拆分, j是分割指针确定递推公式: 如果确定dp[j]是true, 且[j , i]这个区间的子串出现在字典里,…

案例-Shell定时采集数据到HDFS

1. 准备工作 创建日志文件存放的目录 /export/data/logs/log&#xff0c;执行命令&#xff1a;mkdir -p /export/data/logs/log 创建待上传文件存放的目录/export/data/logs/toupload&#xff0c;执行命令&#xff1a;mkdir -p /export/data/logs/toupload 查看创建的目录树结…

FSC在全球范围内增强品牌相关度,促进公众理解

【FSC在全球范围内增强品牌相关度&#xff0c;促进公众理解】 FSC品牌标识 “森林与共&#xff0c;生生不息”将逐渐精简&#xff0c;同时覆盖更多语种。 加深消费者对FSC的理解 近年来&#xff0c;FSC品牌认知度不断提高&#xff0c;超过半数的全球消费者认可并信任“小树”标…

为什么劝你要学习Golang以及GO语言(Go语言知识普及)

Go语言 一、 Go语言的由来 Go语言亦叫Golang语言&#xff0c;是由谷歌Goggle公司推出。 传统的语言比如c&#xff0c;大家花费太多时间来学习如何使用这门语言&#xff0c;而不是如何更好的表达写作者的思想&#xff0c;同时编译 花费的时间实在太长&#xff0c;对于编写-编译…

C语言只推荐这1本宝藏书,你读过吗?

入门的大家随便搜搜学起来都不会出错&#xff0c;进阶的推荐1本豆瓣评分9.1&#xff0c;这本经典之作真正地让人搞懂了烦人的指针。 指针为什么如此重要&#xff1f;C语言圈内有一句经典的自嘲&#xff1a;C语言就只有指针可以用了。如果你干掉struct、干掉union、干掉数组、甚…

html在线阅读小说网页制作模板 小说书籍网页设计 大学生静态HTML网页源码 dreamweaver网页作业 简单网页课程成品

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

管道通信: 有名管道 无名管道,行业大牛通通教会你

管道是一种最古老也是最基本的系统IPC形式&#xff0c;管道就像现实中的水管&#xff0c;水就像数据&#xff0c;它是消息传递的一种特殊方式&#xff0c;管道机制必须提供三方面的协调能力&#xff1a;互斥、同步和确定对方的存在。在Linux中是一种使用非常频繁的通信机制。从…

链表剖析及自己手撸“单链表“实现基本操作(初始化、增、删、改等)

一. 基础 1. 前言 链式存储结构&#xff0c;又叫链表&#xff0c;逻辑上相邻&#xff0c;但是物理位置可以不相邻&#xff0c;因此对链表进行插入和删除时不需要移动数据元素&#xff0c;但是存取数据的效率却很低&#xff0c;分为三类&#xff1a; (1).单(向)链表&#xff1…

【iconfont图标】vue引入并使用阿里巴巴iconfont图标流程

前言 为什么要使用阿里图标库&#xff1a; 图标现在是很多地方都会用到的 一般我使用的时候都是直接在ui库中比如elementul自带的一些 有时候哪怕是感觉图标不是非常适合也是用的elementul图标&#xff0c;主要原因是懒 因为能直接复制的&#xff0c;就懒得再去阿里图标库下载…

如何让Java项目兼容更多的客户端设备(一)

如何让Java项目兼容更多的客户端设备&#xff08;一&#xff09; 引入 HTTP访问是无状态的&#xff0c;&#xff08;服务器不知道是不是你访问的&#xff09;所以我们不知道每次登录的是谁 如果想实现每次登录不用重复登录&#xff0c;最简单的就是让浏览器记住用户名和密码…

球面距离计算方式(杭州到各城市的球面距离计算球面距离)

1&#xff09;杭州到各城市的球面距离 1、数据来源&#xff1a;自主计算 2、时间跨度&#xff1a;至今 3、区域范围&#xff1a;368个城市 4、指标说明&#xff1a;利用城市经纬度&#xff0c;计算球面距离 部分数据如下&#xff1a; &#xff08;2&#xff09;计算两个点之…

Sentinel配置持久化到Nacos实现流控熔断

控制台 jar 下载&#xff1a;github.com/alibaba/Sen… 启动参数 # 将控制台自身接入到sentinel nohup java -jar -Dproject.namesentinel-dashboard -Dcsp.sentinel.dashboard.serverlocalhost:8181 sentinel-dashboard-1.8.5.jar --server.port8181 &> sentinel.log …

单商户商城系统功能拆解38—分销应用—分销订单

c 下面以likeshop单商户高级版 商城系统为例进行功能拆解&#xff0c;likeshop单商户高级版商城系统可以实现快速部署&#xff0c;文档齐全&#xff0c;代码全开源&#xff0c;无加密&#xff0c;极易二次开发&#xff0c;助力企业以极低的成本上线电商业务。并且likeshop以其…

Java项目模块占用CPU过高问题分析

背景&#xff1a;近期一个模块&#xff08;暂且称为A&#xff09;新上了一个需求&#xff0c;改动了些代码&#xff0c;在测试环境部署之后&#xff0c;该模块系统CPU使用率动不动就飙升到90%&#xff0c;甚至200%&#xff0c;严重影像其他业务执行。排查过程 1.使用top查看当…

【LeetCode】813. 最大平均值和的分组

题目描述 给定数组 nums 和一个整数 k 。我们将给定的数组 nums 分成 最多 k 个相邻的非空子数组 。 分数 由每个子数组内的平均值的总和构成。 注意我们必须使用 nums 数组中的每一个数进行分组&#xff0c;并且分数不一定需要是整数。 返回我们所能得到的最大 分数 是多少。答…