Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >java 对象的创建与使用

java 对象的创建与使用

作者头像
用户3147702
发布于 2022-06-27 04:27:23
发布于 2022-06-27 04:27:23
8930
举报

概述

HotSpot 是在 JIT 之后的一款 java 虚拟机的开源实现,sun 从 JDK 1.3.1 开始使用。 它主要使用 C++ 实现的,相对于 JIT,性能有大幅提高。 HotSpot 将部分代码直接编译为本地可执行代码,从而显著提升了性能。

对象的创建

内存分配

java 中,最经常发生的就是对象的创建,那么,虚拟机在 java 对象创建过程中发生了什么呢? 虚拟机遇到一条 new 指令时,首先检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已经被加载、解析和初始化过,如果没有,则执行相应的类加载流程。 接下来,虚拟机为新生对象分配内存,对象所需内存的大小在类加载完成后可以完全确定,因此可以将一块确定大小的内存从 java 堆中划分出来。 在堆中的内存分配有两种方式: 1. 指针碰撞 — 对于在规整的空间中分配内存,只需要将指针向空闲空间挪动一段与对象大小相等的距离,通常在使用 Serial、ParNew 等带 Compact 过程的收集器时采用 2. 空闲列表 — 对于已使用空间和空闲空间交错的情况,指针碰撞就无法使用了,这个时候 jvm 必须维护一个空闲列表,保存每段空闲空间的首地址和长度,分配时 jvm 从列表中查找到足够大的一块空闲空间划分给对象,并更新列表,通常,使用 CMS 这种基于 Mark-Sweep 算法的收集器时采用

原子性

由于 java 是线程模型,所以需要考虑频繁的对象创建的线程安全问题。 有两种方案解决这个问题: 1. 对分配内存的空间进行同步处理,如原子性的比较交换操作配合失败重试 2. 每个线程在 java 堆中预先分配一小块独立的内存,称为本地线程分配缓冲 — TLAB,只有在分配新的 TLAB 时,才需要同步锁定

初始化

jvm 在为对象分配空间后需要将分配的空间初始化为零值,并且根据对象头中的对象信息如哈希码、GC 分代年龄等信息对对象进行必要的设置。 随后,一般来说执行 new 指令之后会接着执行 init 方法,将对象初始化成程序所希望得到的样子。 一个真正可用的对象就完全诞生了。

对象的内存布局

在 HotSpot 虚拟机中,对象在内存中分为三个部分:对象头、实例数据、对齐填充。

对象头 — Header

对象头包含两部分信息: 1. 用于存储对象运行时数据,如哈希码、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等,官方称之为“Mark Word” 2. 类型指针,即对象指向他的类元数据的指针,jvm 通过这个指针来确定这个对象是哪个类的实例

实例数据 — Instance Data

实例数据部分是对象存储的有效信息,也就是程序中定义的各种类型字段内容。

对齐填充 — Padding

这部分数据不是必须存在的,也没有特别含义,因为 HotSpot 是8字节对齐的,因此需要通过对其填充补全8字节。

对象的访问

在 java 栈中,维护了一个本地变量表,当需要访问一个变量时,jvm 就会在本地变量表中查找到变量的类型信息,如果是一个 reference 类型的变量,jvm 就需要去加载相应的对象。 下面的两图分别展示了通过句柄访问对象和通过指针访问对象的存储模式:

使用句柄最大的好处是 reference 中存储的是稳定的句柄地址,在对象移动、垃圾收集等工作中,只需要更新指针,而不需要改变 java 栈中的 reference 的指向(句柄地址不变) 而显然指针访问方式的优势就是速度更快,节省了一次指针定位的开销,对于频繁的对象操作,这类开销累积起来是十分可观的,因此 HotSpot 采用了指针直接访问对象的方式进行对象访问和操作。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
jvm学习记录-对象的创建、对象的内存布局、对象的访问定位
简述 今天继续写《深入理解java虚拟机》的对象创建的理解。这次和上次隔的时间有些长,是因为有些东西确实不好理解,就查阅各种资料,然后弄明白了才来做记录。 (此文中所阐述的内容都是以HotSpot虚拟机为例的。) 对象的创建 java程序在运行过程中无时无刻都有对象被创建出来,那么创建对象是个怎么样的过程呢?还是看看我自己的理解吧。 判断是否已经执行类加载 当虚拟机遇到一条new指令时 ,首先去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已经被加载、解析和初始化
纪莫
2018/04/19
9770
jvm学习记录-对象的创建、对象的内存布局、对象的访问定位
JVM系列一(Java内存区域和对象创建).
线程共享,JVM中最大的一块内存,此内存的唯一目的就是存放对象实例,Java 堆是垃圾收集器管理的主要区域,因此很多时候也被称为“GC堆”(Garbage Collected Heap),可以通过 -Xmx 和 -Xms 参数来控制该区域大小。
JMCui
2019/12/02
4640
JVM系列一(Java内存区域和对象创建).
JVM:全面解析Java对象的创建、内存布局 & 访问定位流程
由于引用类型数据(reference)在 Java虚拟机中只规定了一个指向对象的引用,但没定义该引用应该通过何种方式去定位、访问堆中的对象的具体位置
Carson.Ho
2019/10/25
1.8K0
JVM02-JVM的对象创建以及访问方式
前言对象创建1.类加载检查2.分配内存分配内存的方式内存分配的并发问题3.初始化零值4.设置对象头:5. 执行init方法;对象内存布局对象头实例数据对齐填充对象访问方式使用句柄访问使用直接指针访问总结
码农飞哥
2021/08/18
4960
深入浅出JVM(一)之Hotspot虚拟机中的对象
对象的创建可以分为五个步骤:检查类加载,分配内存,初始化零值,设置对象头,执行实例构造器<init>
菜菜的后端私房菜
2024/09/24
2790
Java类加载及对象创建过程详解
验证阶段作用是保证Class文件的字节流包含的信息符合JVM规范,不会给JVM造成危害。如果验证失败,就会抛出一个java.lang.VerifyError异常或其子类异常。验证过程分为四个阶段:
全菜工程师小辉
2019/08/16
1.4K0
JVM 从入门到放弃之 Java 对象创建过程
当虚拟机遇到一个字节码 new指令的时候,首先去检查这个指令的参数是否能够在常量池中定位到一个类的符号引用。并且检查这个符号引用代表的类是否被虚拟机类加载器加载。如果没有,必须先执行类加载的流程。
没有故事的陈师傅
2022/04/05
6180
JVM 从入门到放弃之 Java 对象创建过程
(3)JVM——对象的创建和内存布局
介绍:在开发中,我们大多是使用 new 关键字来创建对象。但是对于对象的创建具体细节和对象在堆内存中的存储布局不怎么了解,此处主要简单介绍一下。
凡人飞
2020/09/20
6630
JVM-02内存区域与内存溢出异常(中)【hotspot虚拟机对象】
在 JVM-01自动内存管理机制之Java内存区域与内存溢出异常(上)中我们介绍了 运行时数据区域,这里我们来继续探讨下hotspot虚拟机对象
小小工匠
2021/08/17
3630
深入理解java虚拟机-第二章:java内存区域与内存泄露异常
java将内存的管理(主要是回收工作),交由jvm管理,确实很省事,但是一点jvm因内存出现问题,排查起来将会很困难,为了能够成为独当一面的大牛呢,自然要了解vm是怎么去使用内存的。
用户1134788
2018/12/12
5090
JVM-HotSpot虚拟机对象探秘
虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并检查这个符号引用代表的类是否已被加载、解析和初始化过。若没有,则必须先执行相应的类加载过程。
WindCoder
2020/01/21
6840
JVM-HotSpot虚拟机对象探秘
你有认真了解过自己的“Java 对象”吗
作为一名 Javaer,生活中的我们可能暂时没有对象,但是工作中每天都会创建大量的 Java 对象,你有试着去了解下自己的“对象”吗?
海星
2020/07/13
1.1K0
速读原著-HotSpot虚拟机对象探秘
Java 是一门面向对象的编程语言,Java 程序运行过程中每时每刻都有对象被创建出来。在语言 层面上,创建对象通常(例外:克隆、反序列化)仅仅是一个 new 关键字而已,而在虚拟机中, 对象(本文中讨论的对象限于普通 Java 对象,不包括数组和 Class 对象等)的创建又是怎样一个过程呢? 虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载、解析和初始化过的。如果没有,那必须先执行相应的类加载过程。
cwl_java
2020/02/14
4170
Java 虚拟机对象探秘
下图便是 Java 对象的创建过程,建议最好能写出来,并且要掌握每一步在做什么。
Java架构师必看
2021/05/14
3120
Java 虚拟机对象探秘
最通俗易懂的JVM内存管理与对象创建原理
对于Java程序员来说,在虚拟机自动内存管理机制的帮助下,不再需要像 C/C++程序为每一个new操作去写配对 的delete/free代码,不容易出现内存泄漏和内存溢出问题。也正是因为Java程序员把控制内存的权力交给了Java虚拟机,一旦出现内存泄漏和溢出方面的问题,如果不了解虚拟机是怎样使用内存的,那排查错误、修正问题将会成为一项异常艰难的工作。
仲君Johnny
2024/01/24
4800
最通俗易懂的JVM内存管理与对象创建原理
【JVM进阶之路】三:探究虚拟机对象
单纯从语言层面,新建一个对象,可以通过new、反射、复制、反序列化等等。接下来,我们探究以下在虚拟机中,对象的创建是一个什么样的过程。
三分恶
2021/04/01
4440
【JVM进阶之路】三:探究虚拟机对象
Java虚拟机内存管理(二)—堆的使用
Java 虚拟机作为运行 Java 程序抽象出来的计算机,具有内存管理的能力,像内存分配、垃圾回收等这些相关的内存管理问题,Java 虚拟机都会帮我们解决,所以作为一个 Java 程序员要比 C++ 程序员幸福,但是内存方面一旦出现问题,如果对虚拟机怎样使用内存不了解,就很难排查错误。
Wizey
2018/09/29
5320
Java虚拟机内存管理(二)—堆的使用
HotSpot 虚拟机对象
虚拟机遇到一条 new 指令时,首先将去检查这个指令的参数,是否能在常量池中定位到这个类的符号引用,并且检查这个符号引用代表的类是否已被加载过、解析和初始化。如果没有,那必须先执行相应的类加载过程。
happyJared
2019/07/27
5100
一文详解JVM对象内存布局以及内存分配规则
对象头可能包含类型指针,通过该指针能确定对象属于哪个类。如果对象是一个数组,那么对象头还会包括数组长度。
架构狂人
2023/08/16
4010
一文详解JVM对象内存布局以及内存分配规则
3分钟带你了解对象的创建过程
在之前的文章中,我们介绍了类加载的过程和 JVM 内存布局相关的知识。本篇我们综合之前的知识,结合代码一起推演一下对象的真实创建过程,以及对象创建完成之后在 JVM 中是如何保存的。
Java极客技术
2024/02/22
3080
3分钟带你了解对象的创建过程
相关推荐
jvm学习记录-对象的创建、对象的内存布局、对象的访问定位
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档