面试题解,Java中的“对象”剖析

一、说一说JVM中对象的内存布局?new一个对象到底占多大内存?

话不多说,看下图,对象的内存布局图

一个对象的内存布局主要由三部分组成:对象头(Object Header)、实例数据(Instance Data)和对齐填充(Padding)。下面分别介绍这三部分:

对象头(Object Header)

  • Mark Word:存储对象自身的运行时数据,如哈希码、GC分代年龄、锁状态标志等。这部分信息是与对象自身相关的元数据。
  • 类型指针:指向对象类型数据的指针,即该对象属于哪个类的实例。这个地址用于访问类型数据区中的类信息,包括方法表和其他静态变量。

实例数据(Instance Data)

  • 这一部分存放着对象真正有效信息,也就是程序中定义的各种类型的字段内容。这些字段按照从父类到子类的顺序分配内存,同时相同宽度的字段会被分配在一起,以优化空间使用效率。此外,JVM还可能对字段进行重新排序以进一步优化性能,这一过程称为字段排列(Field Layout)。

对齐填充(Padding)

  • JVM要求对象的起始地址必须是8字节的整数倍,这是为了提高CPU缓存命中率和访问速度。

而数组类型的对象,还有4个字节的数组长度字段,所有new一个对象需要的内存大小为:

8byte(对象头) + 4byte(类型指针) + 实例数据 + 填充字段 + 4byte数组长度(若为数组类型)

二、阐述对象的内存分配策略

整体策略如下图所示:

我们来剖析一下:

首先判读是否在栈上分配

  • 在现代JVM中,编译器可能会执行逃逸分析来判断新创建的对象是否只在当前方法或线程内使用。如果一个对象不会“逃逸”出方法的作用域或者被其他线程引用,那么它可以安全地分配在栈上而不是堆上,这被称为标量替换(Scalar Replacement)。这种优化可以减少垃圾回收的压力,并提高性能。

大对象直接进入老年代

  • 如果对象的大小超过了某个阈值(可以通过-XX:PretenureSizeThreshold参数配置),JVM可能会决定直接将该对象分配到老年代,以避免因频繁复制而增加的GC开销。对于非常大的对象,这样的分配策略能够提升性能。

线程本地分配(Thread Local Allocation Buffer, TLAB)

  • 为了减少多线程环境下的锁竞争,每个线程都有自己的小块内存区域(在堆中),称为TLAB。当一个线程需要分配对象时,它首先尝试在自己的TLAB中分配。只有当TLAB空间不足时,才会触发全局同步操作以分配新的TLAB或者直接从共享堆中分配。

对象优先分配到Eden区

  • 如果对象不适合上述任何一种特殊处理,则按照标准的内存分配流程进行,即在年轻代的Eden区分配。如果Eden区没有足够的空间,就会触发一次Minor GC;若GC后仍无足够空间,可能需要晋升部分对象到老年代,甚至引发Full GC。

三、new一个对象都有哪些步骤?

我们来看对象的创建过程,如下图:

1.类加载检查

  • JVM首先检查该类是否已经被加载到内存中。如果尚未加载,则会触发类加载过程,包括加载、链接(验证、准备、解析)和初始化。

2.分配内存

  • 为新对象分配内存空间。这一步骤涉及到如何从堆内存中划分出足够的空间给新对象。内存分配的方式取决于JVM的实现和配置,例如快速失败分配(bump-the-pointer)、线程本地分配缓冲区(TLAB, Thread Local Allocation Buffer)等。
  • 分配过程中还需要考虑对象的对齐填充,确保对象占用的内存是8字节的整数倍,以及处理并发情况下的线程安全问题。

3.内存空间初始化(初始化零值)

  • 在分配完内存后,JVM会对对象的实例变量进行零初始化(zero-initialization),即所有数值型字段被设为0或0.0,引用类型字段被设为null,boolean类型字段被设为false。

4.设置(对象头)

  • 初始化对象头的信息,如哈希码、GC分代年龄、锁状态标志等,并设置指向类元数据的指针,以便知道对象属于哪个类。

5.对象初始化(执行构造函数)

  • 调用类的构造方法来初始化对象的状态。构造方法可以设置成员变量的具体值,并执行其他必要的初始化操作。这是用户代码控制的部分,程序员可以在构造方法中编写自定义逻辑。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

大白话拆解——多线程中关于死锁的一切(七)(已完结)

前言: 25年初,这个时候好多小伙伴都在备战期末 小编明天还有一科考试,日更一篇,今天这篇一定会对小白非常有用的!!! 因为我们会把案例到用代码实现的全过程思路呈现出来!&#xff…

家教老师预约平台小程序系统开发方案

家教老师预约平台小程序系统将连接学生/家长与家教老师,提供一站式的家教服务预约体验。 一、用户需求分析1、家教老师:希望获得更多的学生资源,通过平台展示自己的教学特长和经验,管理个人日程,接收并确认预约请求&a…

windows 图形基础架构简介

背景 本文尝试对Windows系统中的一些Graphic相关的概念进行介绍和厘清。 windows图形基础架构简介 Windows 为图形提供了多个 API,下图显示了这些 API。 上图出自微软官方https://learn.microsoft.com/en-us/windows/win32/learnwin32/overview-of-the-windows-…

QML使用Popup实现弹出Message

方案一:popup import QtQuick 2.15 import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15ApplicationWindow {visible: truewidth: 640height: 480title: qsTr("Top Message Popup Example")ColumnLayout {anchors.centerIn: parentspacing: 10Butt…

Ⅱ.INTRODUCTION TO CUDA C

前言 上一节环境配置好了,我们开始吧! 一、A First Program 1. Hello, World! 我们先写一个C语言的 Hello, World! 作为对比 int main(void){printf("Hello, World!\n");return 0; }大家应该知道这个代码运行在CPU上吧,我们CP…

如何轻松关闭 iPhone 上的 HEIC [HEIC 图像技巧]

您是否正在为关闭 iPhone 上的 HEIC 而烦恼?你不是一个人; Apple 的首选图像文件格式仍可能存在一些兼容性问题。当您与某人共享照片或尝试在Windows计算机上打开图像时,就会出现此问题。幸运的是,Apple 使关闭 HEIC iPhone 变得更加容易。 …

Postgresql 命令还原数据库

因为PgAdmin打不开,但是数据库已经安装成功了,这里借助Pg命令来还原数据库 C:\Program Files\PostgreSQL\15\bin\psql.exe #链接数据库 psql -U postgres -p 5432#创建数据库 CREATE DATABASE "数据库名称"WITHOWNER postgresENCODING UTF8…

docker中使用Volume完成数据共享

情景概述 在一个docker中,部署两个MySQL容器,假如它们的数据都存储在自己容器内部的data目录中。这样的存储方式会有以下问题: 1.无法保证两个MySQL容器中的数据同步。 2.容器删除后,数据就会丢失。 基于以上问题,容…

vue——滑块验证

1. 介绍 1.1 简介 基于滑动式的验证码,免于字母验证码的繁琐输入 用于网页注册或者登录 1.2 来源说明 vue使用滑块验证功能,是基于vue-monoplasty-slide-verify这样的一个开源项目,进行实现的,这是这个开源项目的网址传送阵&#…

如何很快将文件转换成另外一种编码格式?编码?按指定编码格式编译?如何检测文件编码格式?Java .class文件编码和JVM运行期内存编码?

如何很快将文件转换成另外一种编码格式? 利用VS Code右下角的"选择编码"功能,选择"通过编码保存"可以很方便将文件转换成另外一种编码格式。尤其,在测试w/ BOM或w/o BOM, 或者ANSI编码和UTF编码转换,特别方便。VS文件另…

Unity3D仿星露谷物语开发16之角色拾取道具

1、目标 当角色经过道具时会拾取道具放到库存列表中,此时道具消失并打印库存信息。 2、创建新的Enum 在Assets -> Scripts -> Enums -> Enum.cs中添加库存位置相关的信息。 public enum InventoryLocation {player, // 在角色手中chest, // 在箱子里co…

UE4_用户控件_3_用户控件输入数据的方法

祝愿大美兰陵越来越好! 一、效果展示: 二、先制作一个角色 1、新建个父类为pawn的蓝图类。更名为BP_Image_Character。 2、这个角色只是用于观察场景,并与场景中的物体相碰撞用的,所以不需要骨骼网格体, 3、但是我们…

文献阅读 | B. S. Carmo 2010

目录 一、文献名称二、原文地址三、ABSTRACT主要发现详细观察分岔分析雷诺数依赖性比较见解意义结论 四、IINTRODUCTION历史研究回顾计算研究近期研究进展研究空白与目的论文结构 一、文献名称 二、原文地址 研究目的:研究串列排列双圆柱体周围流场中的次级不稳定性…

vue3 css实现文字输出带光标显示,文字输出完毕,光标消失的效果

Vue实现过程如下&#xff1a; <template><div ><p ref"dom_element" class"typing" :class"{over_fill: record_input_over}"></p></div> </template> <script setup> import {onMounted, ref} from…

如何安装适配pytorch版本的torchvision

一、对照版本 版本对照pytorch/vision: Datasets, Transforms and Models specific to Computer Vision 二、下载对应版本的torchvision 下载连接1download.pytorch.org/whl/torch_stable.html 下载连接2download.pytorch.org/whl/cu110/torch_stable.html 笔者认为1会比2更…

Leetcode打卡:我的日程安排表III

执行结果&#xff1a;通过 题目 732 我的日程安排表 III 当 k 个日程存在一些非空交集时&#xff08;即, k 个日程包含了一些相同时间&#xff09;&#xff0c;就会产生 k 次预订。 给你一些日程安排 [startTime, endTime) &#xff0c;请你在每个日程安排添加后&#xff0c;…

TI毫米波雷达原始数据解析之Lane数据交换

TI毫米波雷达原始数据解析之Lane数据交换 背景Lane 定义Lane 确认确认LVDS Lane 数量的Matlab 代码数据格式参考 背景 解析使用mmWave Studio 抓取的ADC Data Lane 定义 芯片与DCA100之间的数据使用LVDS接口传输&#xff0c;使用mmWave Studio 配置过程中有一个选项是LVDS L…

redis7基础篇3 redis的集群模式3

一 集群模式 1.1 redis的集群模式 Redis集群模式&#xff0c;实现数据集在多个节点进行共享&#xff0c;支持多个master节点。 Redis集群支持多个master&#xff0c;每个master节点又可以挂载多个slave&#xff1b;由于cluster自带sentinel的故障转移机制&#xff0c;内置高…

【嵌入式硬件】直流电机驱动相关

项目场景&#xff1a; 驱动履带车&#xff08;双直流电机&#xff09;前进、后退、转弯 问题描述 电机驱动MOS管烧毁 电机驱动采用IR2104STRH1R403NL的H桥方案&#xff08;这是修改之后的图&#xff09; 原因分析&#xff1a; 1.主要原因是4路PWM没有限幅&#xff0c;修改…

部署项目添加工程名的步骤

1.首先要在router下进行工程名添加 2.其次在vue.config.js中添加publicpath 3.在nginx配置文件中 location /my-app/ {try_files $uri $uri/ /my-app/index.html; }