JVM笔记(7)—— Java对象创建的过程

news2024/11/27 16:31:59

一、对象创建的六种方式

在这里插入图片描述

1. new关键字

直接通过new关键字调用类的构造器创建

2. Class的newInstance()方法

通过类对象的newInstance()方法利用反射创建对象,只能调用权限为public的空参构造器,若对应类没有此构造器则会抛出编译时异常ClassNotFoundException

        //通过反射获取Test类的类对象
        Class cl1 = Class.forName("com.classLoader.Test");
        //调用Test类中权限为public的空参构造器创建对象
        //创建出的对象为object类型
        Object o1 = cl1.newInstance();

        Test o2 = (Test)o1;
        Class cl2 = o2.getClass();

        
        System.out.println("cl1 == cl2 " + (cl1 == cl2));//true 同一个类的类对象在jvm中只存在一个
        System.out.println("o1 == o2: " + (o1 == o2));//true 引用类型的强转只是返回一个新的引用变量,其指向的对象的存储地址没有改变

使用条件苛刻,jdk9后这个方法已经被标记为过时的了,需要反射创建对象时更推荐直接使用Constructor,Class的newInstance()方法中也是用的Constructor进行创建的,只不过在调用前加了限制。

3. Constructor的newInstance()方法

通过Constructor利用反射来创建对象,可调用类中任意构造器

        Class clazz = Class.forName("com.createObject.Test");

        //获取空参构造器创建对象
        Constructor constructor1 = clazz.getDeclaredConstructor();
        Object o1 = constructor1.newInstance();

        //获取参数类型为String的构造器创建对象
        Constructor constructor2 = clazz.getDeclaredConstructor(String.class);
        Object o2 = constructor2.newInstance("Hello");

4. 使用clone()方法

通过一个对象的clone()方法拷贝一个新的对象,对象所属类需要重写clone()方法,并实现Cloneable接口。若重写方法中直接调用父类Object的clone()方法,则为浅拷贝(即对于原对象中的引用类型变量,拷贝时直接复制引用,而非再复制一份对象)

		Test o1 = new Test();
        Test o2 = o1.clone();
        System.out.println("o1 == o2: " + (o1 == o2));//false 拷贝的对象为一个新的对象

在这里插入图片描述

5. 使用反序列化

将从文件或网络中获取一个对象的二进制流反序列化为对象。常用的反序列化方式有下面两种

(1)Java原生类ObjectInputStream

这是jdk自带的反序列化方式,序列化对象的类需要实现了Serializable或Externalizable接口

//将对象序列化并存储在文件中
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D:\\object.out"));
oos.writeObject(new User("xuliugen", "123456", "male"));

//从文件中读取对象的二进制流并反序列化为对象
ObjectInputStream ois= new ObjectInputStream(new FileInputStream("object.out"));
User user = (User) ois.readObject();

(2)JSON库

一些常见JSON库可以实现将一个对象序列化为一个json字符串,或者将json字符串反序列化为一个对象

Test o1 = new Test();
//fastjson 将对象序列化为json格式字符串
String jsonStr = JSON.toJSONString(o1);
//fastjson 反序列化字符串为对象
JSONObject jsonObject = JSON.parseObject(jsonStr);
Test o2 = JSON.toJavaObject(jsonObject, Test.class);

fastjson库中有两套序列化/反序列化框架。第一套是常规的,序列化的原理是将对象的属性名和属性值转换成JSON中的key和value,反序列化的原理是通过反射来set对应的属性值生成对象。第二套是基于ASM字节码框架,通过ASM减少了很多反射的开销,因此速度更快,默认是这套。具体原理感兴趣可参考:

  1. Fastjson源码分析—ASM的作用和实现(1)
  2. 分析FastJSON为何那么快与字节码增强技术揭秘

6. 其他第三方库

还有一些其他第三方库可以用一些特殊的方式创建对象,例如Objenesis库。Spring中就集成了Objenesis库,在使用Cglib创建动态代理对象时就使用到了Objenesis。
参考:java中Objenesis库简单使用

二、对象创建的六个步骤

在这里插入图片描述

1. 判断对象对应的类是否已加载

以当前类加载器+类全名作为key在方法区中查找类是否加载,若没有则通过双亲委派模式尝试加载,若没有找到则抛出ClassNotFoundException

2. 为对象分配内存

首先计算对象占用空间大小,然后在堆中分配一块内存给新对象。

如果JVM采用的垃圾收集器采用的是标记压缩算法,即回收后会将剩余对象整理到连续的内存空间,使得堆内存规整,则JVM中给对象分配内存的方式是指针碰撞,即在已使用的空间后连续分配内存,以继续保持内存规整。

如果JVM采用的垃圾收集器采用的是标记清除算法,则堆内存是不规整的,已使用的内存和未使用的内存相互交错,那么虚拟机采用的是空闲列表法来为对象分配内存。意思是虚拟机维护了一个列表,记录哪些内存块是可用的,分配内存时在列表中找到一块足够大的空间分配给对象,再更新列表。

3. 处理并发安全问题

由于在堆中创建对象这个操作非常频繁,如果不对堆内存特殊处理,就可能出现并发安全问题。处理方式有两种:
(1)CAS+失败重试
CAS 是乐观锁的一种实现方式。所谓乐观锁就是,每次不加锁而是假设没有冲突而去完成某项操作,如果因为冲突失败就重试,直到成功为止。虚拟机采用 CAS 配上失败重试的方式保证更新操作的原子性。
(2)每个线程预先分配一块TLAB
为每一个线程预先在 Eden 区分配一块儿内存,JVM 在给线程中的对象分配内存时,首先在 TLAB 分配,当对象大于 TLAB 中的剩余内存或 TLAB 内存已用尽时,再采用上述的 CAS 进行内存分配。

可通过-XX:+/-UseTLAB选项来配置jvm是否使用TLAB,默认是开启的

4. 初始化分配到的空间

给对象的所有属性(包括继承的父类的属性)设置默认值。例如int类型属性默认初始化为0

5. 设置对象的对象头

将对象的所属类(即类的元数据信息)、对象的HashCode和对象的GC信息、锁信息等数据存储在对象的对象头中。这个过程的具体设置方式取决于JVM实现。

6. 执行init方法进行初始化

执行init方法初始化对象,包括对属性的显式初始化、执行代码块、执行构造器函数

java在编译后会在字节码文件中生成<init>方法,称为实例构造器,其中包括属性显式初始化/代码块/构造函数

三、对象的内存布局

1. 对象的内存布局

堆中一个对象的空间中除了存储对象的属性外,还有对象头(markword、类型指针)和对齐填充。对象的内存布局如下:

在这里插入图片描述

在这里插入图片描述

2. 案例

在这里插入图片描述

public class CustomerTest {
	public static void main(string[] args) {
		Customer cust = new customer();
	}
}

如上程序在创建Customer对象后jvm整体状态如下:

在这里插入图片描述

四、对象的访问定位方式

JVM是如何通过栈帧中的对象引用访问到对应的对象实例的呢?有两种如下方式

1. 句柄访问

通过在Java堆设置一个句柄池实现间接访问
优点:垃圾回收整理对象改变了对象位置后只需要修改句柄池中的指针,局部变量表中的引用指针无需改变
缺点:句柄池要占用一块存储空间,并且间接访问的方式效率较低
在这里插入图片描述

2. 使用直接指针(Hotspot采用)

使用直接指针直接访问
优点:访问速度比句柄访问更快
缺点:对象移动后需要同时修改栈中所有指向了这个对象的指针,要麻烦一些
在这里插入图片描述

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

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

相关文章

redis基本入门| 怎么安装redis?什么的是redis?怎么使用?

目录 一、Redis下载与安装 二、基本概念 1.什么是Redis? 2.Redis端口多少&#xff1f; 3.Redis是单线程还是多线程&#xff1f; 4.Redis为什么单线程还这么快&#xff1f; 三、Redis的基本操作 四、Redis的五个基本类型 1.Redis-key 2.字符串 string 3.列表 list …

七大软件架构设计原则-读书笔记

7大原则 开闭原则&#xff08;Open-Closed Principle&#xff0c;OCP&#xff09; 指一个软件实体如类、模块和函数应该对扩展开放&#xff0c;对修改关闭。强调的是用抽象构建框架&#xff0c;用实现扩展细节&#xff0c;可以提高软件系统的可复用性及可维护性。开闭原则是面…

浅谈Redisson实现分布式锁对原理

1.Redisson简介 Redis 是最流行的 NoSQL 数据库解决方案之一&#xff0c;而 Java 是世界上最流行&#xff08;注意&#xff0c;我没有说“最好”&#xff09;的编程语言之一。虽然两者看起来很自然地在一起“工作”&#xff0c;但是要知道&#xff0c;Redis 其实并没有对 Java…

Win10开机输入密码后1分钟左右就蓝屏,一天出现10个不同蓝屏代码,如何解决

环境: DELL3480 Win10 专业版 问题描述: Win10 电脑开机输入密码后1分钟左右突然就蓝屏,一天出现10个不同蓝屏代码 1.BAD_SYSTEM_CONFIG_INFO bug 检查的值为 0x00000074。 此 bug 检查指示注册表中出现错误。 2.PAGE_FAULT_IN_NONPAGED_AREA bug 检查的值为 0x000…

修改redis的配置文件使得windows的图形界面客户端可以连接redis服务器

1. 安装 Redis 依赖 Redis 是基于 C语言编写的&#xff0c;因此首先需要安装 Redis 所需要的 gcc 依赖&#xff1a; yum install -y gcc tcl 2、上传安装文件 将下载好的 redis-6.2.7.tar.gz 安装包上传到虚拟机的任意目录&#xff08;一般推荐上传到 /usr/local/src目录&…

linux集群技术(三)--七层负载均衡-nginx

nginx特点nginx优势、缺点生产架构nginx 7层负载均衡语法示例nginx负载均衡算法测试案例生产案例 1.nginx特点 1. 功能强大,性能卓越,运行稳定。 2. 配置简单灵活。 3. 能够自动剔除工作不正常的后端服务器。 4. 上传文件使用异步模式。client---nginx---web1 web2 web3 lvs同…

uniapp: 基础开发官网文档

1、uniapp官网文档&#xff1a;https://uniapp.dcloud.net.cn/component/2、uView跨端UI组件库&#xff1a;http://v1.uviewui.com/components/intro.html3、lunch-request&#xff08;类似axios的请求库&#xff09;&#xff1a;https://www.quanzhan.co/luch-request/handboo…

图神经网络基础 Graph 图以及python实现

摘要&#xff1a; 本文将介绍图的基本知识、无向图、有向图、邻接矩阵 python实现&#xff1a;度、连通分量、强连通图、弱连通图、图直径、度中心性、特征向量中心性、中介中心性、连接中心性等基本概念。 python计算代码&#xff1a; 先安装依赖&#xff1a; pip install n…

Java-模块化

模块的基本使用 模块使用步骤 创建模块&#xff08;创建模块&#xff0c;创建包&#xff0c;创建类&#xff0c;定义方法&#xff09; -创建两个模块myOne,myTwo在模块的src目录下创建module-info.java的描述性文件&#xff0c;该文件专门定义模块名&#xff0c;访问权限&#…

一文读懂函数编程及其工作原理

微软MVP实验室研究员 马洪喜-微软 MVP 19年研发经验 云计算咨询顾问专家 容器云及基础架构云技术专家 DevOps 及微服务咨询专家 什么是函数编程 我先用通俗的大白话给大家解释一下函数(Functions, Function as a Service, FaaS)的几个要点&#xff0c;这样看后面示例时才不…

跑步带的耳机选择啥样的好、推荐几款跑步专用耳机

我是个比较喜欢运动的人&#xff0c;每天下班都会在小区湖边跑步健身&#xff0c;每次跑步要是少了耳机&#xff0c;那可没什么兴趣跑了&#xff0c;喜欢跑步的时候对着音乐的节奏跑&#xff0c;所以我的耳机基本上是用的比较紧实不易掉落的无线耳机。接下来我来为大家介绍下我…

ChatGPT 可收费的那种产品该如何实现?一点尝试

导读|时隔两个月&#xff0c;勇哥终于把chatGPT生成SQL的功能发布上线了&#xff0c;支持统计分析查询、创建表、数据生成等多种全面的SQL DDL生成能力&#xff0c;本文就和大家聊聊相关功能的使用和背后实现逻辑&#xff0c;并希望相关功能能帮助大家在工作中提升一定的工作效…

手把手搭建springboot项目05-springboot整合Redis及其业务场景

目录前言一、食用步骤1.1 安装步骤1.1.1 客户端安装1.2 添加依赖1.3 修改配置1.4 项目使用1.5 序列化二、应用场景2.1 缓存2.2.分布式锁2.2.1 redis实现2.2.2 使用Redisson 作为分布式锁2.3 全局ID、计数器、限流2.4 购物车2.5 消息队列 (List)2.6 点赞、签到、打卡 (Set)2.7 筛…

如何弄小程序?公司企业可以这样做小程序

公司企业现在对于小程序的需求已经是刚需了&#xff0c;即使已经有官网的情况下&#xff0c;也会考虑再弄一个小程序来做小程序官网。那么公司企业如何弄小程序呢&#xff1f;下面跟大家说说方法。 流程一、找小程序服务商 由于一些公司企业并不像现在的互联网公司企业那样有…

考试系统 (springboot+vue前后端分离)

系统图片 下载链接 地址&#xff1a; http://www.gxcode.top/code 介绍 一款多角色在线培训考试系统&#xff0c;系统集成了用户管理、角色管理、部门管理、题库管理、试题管理、试题导入导出、考试管理、在线考试、错题训练等功能&#xff0c;考试流程完善。 技术栈 Spr…

Java8中@Contended和伪共享

Java8引入了Contented这个新的注解来减少伪共享(False Sharing)的发生。 sun.misc.Contended注解是被设计用来解决伪共享问题的 文章目录1.缓存行2.伪共享(False Sharing)2.1 CPU的缓存机制3.填充(Padding)4.Contended方式4.总结1.缓存行 CPU读取内存数据时并非一次只读一个字…

ATTCK实战系列——红队实战(二)

网络配置 网卡&#xff1a; WEB&#xff1a; PC&#xff1a; DC&#xff1a; IPWEB10.10.10.80&#xff08;内&#xff09;/192.168.111.80&#xff08;外&#xff09;PC10.10.10.201&#xff08;内&#xff09;/192.168.111.201&#xff08;外&#xff09;DC10.10.10.10物理机…

评论字数统计案例、评论回车发布、 Tab 栏切换、验证码倒计时、显示与隐藏密码——DOM事件

目录 一、DOM事件 1. 评论字数统计案例 2. 评论回车发布 3. Tab 栏切换 4. 验证码倒计时 5. 显示与隐藏密码 一、DOM事件 1. 评论字数统计案例 该案例中的显示输入字数及最大字数模块.wrapper .total 刚开始是看不见的&#xff0c;使用的是不透明度&#xff08;opacit…

量化交易-单因子分析-alphalens

1. 数据准备 1.1 计算因子IC重要函数 def get_clean_factor_and_forward_returns(factor,prices,groupbyNone,binning_by_groupFalse,quantiles5,binsNone,periods(1, 5, 10),filter_zscore20,groupby_labelsNone,max_loss0.35,zero_awareFalse,cumulative_returnsTrue)facto…

Nginx优化与防盗链

Nginx优化与防盗链 &#x1f4d2;博客主页&#xff1a; 微笑的段嘉许博客主页 &#x1f4bb;微信公众号&#xff1a;微笑的段嘉许 &#x1f389;欢迎关注&#x1f50e;点赞&#x1f44d;收藏⭐留言&#x1f4dd; &#x1f4cc;本文由微笑的段嘉许原创&#xff01; &#x1f4c…