当前位置: 首页 > news >正文

【JVM】详解对象的创建过程

文章目录

  • 1、创建对像的几种方式
    • 1、new关键字
    • 2、反射
    • 3、clone
    • 4、反序列化
  • 2、创建过程
    • 步骤 1、检查类是否已经被加载
    • 步骤 2、 为对象分配内存空间
      • 1、指针碰撞
        • 针对指针碰撞线程不安全,有两种方案:
      • 2、空闲列表
      • 选择哪种分配方式
    • 步骤3、将内存空间初始化为零值
    • 步骤4、对对象进行必要的设置
    • 步骤5、执行实例的初始化方法init
  • 总结
  • 注意

谈对象的创建过程的话,先来介绍介绍创建对象的几种方式

1、创建对像的几种方式

1、new关键字

通过调用类的构造方法创建对象
在这里插入图片描述

2、反射

通过反射创建对象的方式又有两种:
一种是通过Class.newInstance
在这里插入图片描述

另一种是通过调用构造器再去创建对象Constructor.newInstance:
先通过反射获取类中无参构造器,然后通过newInstance()获取对象
在这里插入图片描述

3、clone

通过Clone创建对象,首先实体类中必须先实现Cloneable接口并复写Object的clone方法(因为Object的这个方法是protected的)
在这里插入图片描述
在这里插入图片描述

4、反序列化

序列化:指把 Java 对象转换为字节序列的过程;
反序列化:指把字节序列恢复为 Java 对象的过程;
此方式需要类先实现Serializable接口

public class UserParam implements Serializable
public class Test {public static void main(String[] args) throws IOException, ClassNotFoundException {File file =new File("E:/Serializable.txt");FileOutputStream fileOutputStream = new FileOutputStream(file);ObjectOutputStream outputStream = new ObjectOutputStream(fileOutputStream);UserParam userParam =new UserParam("aaaa");outputStream.writeObject(userParam);FileInputStream fileInputStream  = new FileInputStream(file);ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);UserParam userParam1 = (UserParam)objectInputStream.readObject();userParam1.setNickName("bbbbbbb");System.out.println(userParam1);}}

通过阅读上面介绍的几种创建对象的方法,大家一定对new、newInstance背后的工作产生了好奇,那么下面我将介绍创建一个对象的流程:

2、创建过程

当Java虚拟机遇到一条字节码new指令时

步骤 1、检查类是否已经被加载

去常量池中查找该引用所指向的类有没有被虚拟机加载,如果没有被加载,那么会进行类的加载过程。类的加载过程需要经历:加载、链接、初始化三个阶段。对象的大小,在类加载完成时确定。
(jdk1.8中,运行时常量池、类常量池存在于方法区中。)

步骤 2、 为对象分配内存空间

JVM为对象分配空间,即把一块确定大小的内存块从Java堆中划分出来。

1、指针碰撞

假设Java堆中内存是绝对规整的,所有被使用过的内存都被放在一边,空闲的内存被放在另一边,中间放着一个指针作为分界点的指示器,那所分配内存就仅仅是把那个指针向空闲空间方向挪动一段与对象大小相等的距离。

正常状态:
在这里插入图片描述
为对象分配内存:
在这里插入图片描述

这种方式的优点是工作简单,效率高,只需要移动指针就可以分配内存空间。

缺点也很明显:由于用指针碰撞分配内存空间分为两步,1、读取指针当前的位置 2、根据自身大小移动指针,不是原子操作,对象创建在虚拟机中是非常频繁的操作,在并发情况下,会导致执行读操作或执行写操作的结果与预设的结果不一致(指针划分不一致)。
例如:线程A要给对象分配8kb,读取到指针当前的位置,时间片用完,切换到线程B,线程B要给它的对象分配16kb,也读取到指针当前的位置(和线程A读取到的一样),将指针向空闲内存方向移动16kb大小,线程B时间片用完,切换到线程A继续执行,由于线程A使用的指针位置还是之前读到的。(线程不安全问题)

针对指针碰撞线程不安全,有两种方案:

  1. 同步处理(加锁)分配内存空间行为

采用 CAS 分配重试的方式来保证更新操作的原子性

  1. 把内存分配行为按照线程,划分在不同的内存空间进行
  1. 即每个线程在Java堆中预先分配一小块内存,称为本地线程分配缓冲(Thread Local Allocation Buffer,TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲区用完
    了,分配新的缓存区时才需要同步锁定
  2. 虚拟机是否使用TLAB,可以通过-XX:+/-UseTLAB参数来
    设定。

2、空闲列表

如果Java堆中的内存并不是规整的, 已被使用的内存和空闲的内存相互交错在一起,那就没有办法简单地进行指针碰撞了,虚拟机就必须维护一个列表,记录上哪些内存块是可用的,在分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表上的记录。

选择哪种分配方式

两种方式的选择由 Java 堆是否规整决定,Java 堆是否规整是由选择的垃圾收集器是否具有压缩整理能力决定的。

步骤3、将内存空间初始化为零值

内存分配完成之后,虚拟机必须将分配到的内存空间(但不包括对象头)都初始化为零值。零值初始化意思就是对对象的字段赋0值,或者null值,这也就解释了为什么这些字段在不需要进程初始化时候就能直接使用。
如果使用了TLAB的话,这一项工作也可以提前至TLAB分配时顺便进行。

步骤4、对对象进行必要的设置

例如这个对象是哪个类的实例、如何才能找到类的元数据信息、对象的哈希码、对象的GC分代年龄等信息。这些信息存放在对象的对象头中。

从虚拟机的视角来看,一个新的对象已经产生了。但是从Java程序的视角看来,对象创建才刚刚开始——构造函数,即Class文件中的()方法还没有执行,所有的字段都为默认的零值,对象需要的其他资源和状态信息也还没有按照预定的意图构造好。

步骤5、执行实例的初始化方法init

init方法包含成员变量、构造代码块的初始化,按照声明的顺序执行,执行对象的构造
方法,并把堆内对象的首地址赋值给引用变量。至此,对象创建成功。

总结

在这里插入图片描述

注意

并发情况下,需要考虑操作的步骤是不是原子性,如果不是,就要加锁。原子性就是动作不能再继续被拆分了,读是原子性,写也是原子性,但是读+写就不是原子性

相关文章:

【JVM】详解对象的创建过程

文章目录 1、创建对像的几种方式1、new关键字2、反射3、clone4、反序列化 2、创建过程步骤 1、检查类是否已经被加载步骤 2、 为对象分配内存空间1、指针碰撞针对指针碰撞线程不安全,有两种方案: 2、空闲列表选择哪种分配方式 步骤3、将内存空间初始化为…...

华纳云:ubuntu下如何搭建nfs服务

在Ubuntu下搭建NFS(Network File System)服务,可以实现网络文件共享。以下是在Ubuntu上搭建NFS服务的步骤: 安装NFS服务器和客户端软件: 打开终端,并使用以下命令安装NFS服务器和客户端软件: sudo apt-get update s…...

HCIA实验二

实验要求: 1.R2为ISP,只能配置IP 2.R1-R2之间为HDLC封装 3.R2-R3之间为PPP封装,pap认证,R2为主认证方 4.R2-R4之间为PPP封装,chap认证,R2为主认证方 5.R1、R2、R3构建MGRE,仅R1的IP地址固定…...

stm32 舵机 cubemx

文章目录 前言一、cubemx配置二、代码1.serve.c2.serve.h3.主函数 总结 前言 stm32对舵机进行控制,很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此&#…...

无涯教程-jQuery - Spinner组件函数

Widget Spinner 函数可与JqueryUI中的窗口小部件一起使用。Spinner提供了一种从一组中选择一个值的快速方法。 Spinner - 语法 $( "#menu" ).selectmenu(); Spinner - 示例 以下是显示Spinner用法的简单示例- <!doctype html> <html lang"en"…...

Python 有趣的模块之pynupt——通过pynput控制鼠标和键盘

Python 有趣的模块之pynupt ——通过pynput控制鼠标和键盘 文章目录 Python 有趣的模块之pynupt ——通过pynput控制鼠标和键盘1️⃣简介2️⃣鼠标控制与移动3️⃣键盘控制与输入4️⃣结语&#x1f4e2; 1️⃣简介 &#x1f680;&#x1f680;&#x1f680;学会控制鼠标和键盘是…...

docker基于centos7镜像安装python3.7.9

下载centos7镜像 docker pull centos&#xff1a;centos7 启动容器centos-python-3.7 docker run -itd --name centos-python-3.7 -p 60021:22 --privileged centos:centos7 /usr/sbin/init 进入容器 docker exec -it centos-python-3.7 /bin/bash centos7环境下安装python3.7.…...

JavaScript中的switch语句

switch语句和if语句一样&#xff0c;同样是运用于条件循环中&#xff1b; 下面例子我们用switch实现 例如如果今天是周一就学习HTML&#xff0c;周二学习CSS和JavaScript&#xff0c;周三学习vue&#xff0c;周四&#xff0c;周五学习node.js&#xff0c;周六周日快乐玩耍&…...

Jquery笔记

DOM对象通过jquery获取 所有的代码都是基于引入jquery.js文件 var mydiv $(#div);//直接获取到DOM对象元素id var mydiv$(.div)&#xff1b;//通过class获取DOM对象&#xff0c;如果有同名class只会获取第一个 var mysapn$(span);//通过元素的标签名获取DOM对象 var divarr$(…...

【C++】优先级队列的基本概念以及其模拟实现

文章目录 补充知识&#xff1a;仿函数一、优先级队列&#xff1a;1.引入2.介绍 二、priority_queue的模拟实现1.大体框架2.私有成员函数&#xff1a;1.向下调整&#xff08;AdjustDown&#xff09;2.向上调整&#xff08;AdjustUp&#xff09; 3.公有成员函数1大小&#xff08;…...

TextClamp for Vue3.0(Vue3.0的文本展开收起组件)

呦&#xff01;大家好&#xff0c;好久没有更新博客了&#xff0c;最近实现了一个一直想自己完成的一个东西&#xff0c;就是文本的展开收起组件&#xff0c;以前项目需要用到&#xff0c;自己实现一个又太繁琐&#xff0c;所以那个时候都是用的别人的轮子&#xff0c;现在自己…...

区间预测 | MATLAB实现VAR向量自回归时间序列区间预测

区间预测 | MATLAB实现VAR向量自回归时间序列区间预测 目录 区间预测 | MATLAB实现VAR向量自回归时间序列区间预测预测效果基本介绍程序设计参考资料预测效果 基本介绍 区间预测 | MATLAB实现VAR向量自回归时间序列区间预测 VAR(Vector Autoregression)模型是一种广泛应用于时…...

在 Windows 上搭建 NTP 服务器

文章目录 一、基础环境二、适用场景三、操作步骤四、常用的NTP服务器五、参考资料 版权声明&#xff1a;本文为博主原创文章&#xff0c;于2023年7月30日首发于CSDN&#xff0c;转载请附上原文出处链接和本声明。本文链接&#xff1a;https://blog.csdn.net/u011046671 一、基础…...

应急响应经典案例-FTP 暴力破解

应急响应经典案例-FTP 暴力破解 应急场景日志分析应急处理措施 应急场景 从昨天开始&#xff0c;网站响应速度变得缓慢&#xff0c;网站服务器登录上去非常卡&#xff0c;重启服务器就能保证一段时间的正常访问&#xff0c;网站响应状态时而飞快时而缓慢&#xff0c;多数时间是…...

41. linux通过yum安装postgresql

文章目录 1.下载安装包2.关闭内置PostgreSQL模块:3.安装postgresql服务:4.初始化postgresql数据库:5.设置开机自启动:6.启动postgresql数据库7.查看postgresql进程8.通过netstat命令或者lsof 监听默认端口54329.使用find命令查找了一下postgresql.conf的配置位置10.修改postgre…...

SpringBoot启动流程及自动配置

SpringBoot启动流程源码&#xff1a; 1、启动SpringBoot启动类SpringbootdemoApplication中的main方法。 SpringBootApplication public class SpringbootdemoApplication {public static void main(String[] args) {SpringApplication.run(SpringbootdemoApplication.class, …...

【Linux】进程轻松入门

目录 一&#xff0c; 冯* 诺依曼体系结构 1&#xff0c;存储结构 ​编辑 二&#xff0c; 操作系统 1&#xff0c;概念 2&#xff0c;设计OS的目的 3&#xff0c;定位 4&#xff0c;如何理解 "管理" 5&#xff0c; 总结 三&#xff0c;进程 1. 概念 那么…...

【使用时空RBF-NN进行非线性系统识别】实现了 RBF、分数 RBF 和时空 RBF 神经网络,用于非线性系统识别研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

Tomcat 安装配置教程及成功后,启动失败报错解决方案

解决方案 我的报错原因是因为我的JDK是1.8的而我的Tomcat是10版本的&#xff0c;可能是因为版本原因吧&#xff0c;我重新装了Tomcat 9就可以启动成功了&#xff01; 简单说下安装的时候需要注意哪些步骤吧 今天我在安装tomcat10的时候&#xff0c;安装成功后&#xff0c;启…...

C#文件操作从入门到精通(2)——查看某个dll中有哪些函数

kernel32.dll中含有ini文件操作使用的函数,我们可以通过VisualStudio自带的dumpbin.exe查看dll所包含的函数,操作步骤如下: 1、找到dumpbin.exe所在的文件夹 我的电脑中安装了VisualStudio2019社区版以及VisualStudio2017Professional,但是我发现VisualStudio2019社区版中…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

服务器硬防的应用场景都有哪些?

服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式&#xff0c;避免服务器受到各种恶意攻击和网络威胁&#xff0c;那么&#xff0c;服务器硬防通常都会应用在哪些场景当中呢&#xff1f; 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...

AI,如何重构理解、匹配与决策?

AI 时代&#xff0c;我们如何理解消费&#xff1f; 作者&#xff5c;王彬 封面&#xff5c;Unplash 人们通过信息理解世界。 曾几何时&#xff0c;PC 与移动互联网重塑了人们的购物路径&#xff1a;信息变得唾手可得&#xff0c;商品决策变得高度依赖内容。 但 AI 时代的来…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1&#xff09;下载安装包2&#xff09;配置环境变量3&#xff09;安装镜像4&#xff09;node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1&#xff09;使用 http-server2&#xff09;详解 …...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...

comfyui 工作流中 图生视频 如何增加视频的长度到5秒

comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗&#xff1f; 在ComfyUI中实现图生视频并延长到5秒&#xff0c;需要结合多个扩展和技巧。以下是完整解决方案&#xff1a; 核心工作流配置&#xff08;24fps下5秒120帧&#xff09; #mermaid-svg-yP…...

node.js的初步学习

那什么是node.js呢&#xff1f; 和JavaScript又是什么关系呢&#xff1f; node.js 提供了 JavaScript的运行环境。当JavaScript作为后端开发语言来说&#xff0c; 需要在node.js的环境上进行当JavaScript作为前端开发语言来说&#xff0c;需要在浏览器的环境上进行 Node.js 可…...

基于django+vue的健身房管理系统-vue

开发语言&#xff1a;Python框架&#xff1a;djangoPython版本&#xff1a;python3.8数据库&#xff1a;mysql 5.7数据库工具&#xff1a;Navicat12开发软件&#xff1a;PyCharm 系统展示 会员信息管理 员工信息管理 会员卡类型管理 健身项目管理 会员卡管理 摘要 健身房管理…...