iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >如何用JVM源码分析Java对象的创建过程
  • 483
分享到

如何用JVM源码分析Java对象的创建过程

2023-06-17 04:06:39 483人浏览 泡泡鱼
摘要

这篇文章将为大家详细讲解有关如何用JVM源码分析Java对象的创建过程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。基于HotSpot实现对Java对象的创建过程进行深入分析。定义两个简单的

这篇文章将为大家详细讲解有关如何用JVM源码分析Java对象的创建过程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

基于HotSpot实现对Java对象的创建过程进行深入分析。

定义两个简单的类AAA和BBB

如何用JVM源码分析Java对象的创建过程

通过“javap -c AAA“`查看编译之后的字节码,具体如下:

如何用JVM源码分析Java对象的创建过程

Java中的new关键字对应jvm中的new指令,定义在InterpreterRuntime类中,实现如下:

如何用JVM源码分析Java对象的创建过程

new指令的实现过程:
1、其中pool是AAA的constant pool,此时AAA的class已经加载到虚拟机中,new指令后面的#2表示BBB类全限定名的符号引用在constant pool的位置;
2、方法pool->klass_at负责返回BBB对应的klassOop对象,实现如下:

如何用JVM源码分析Java对象的创建过程

如果常量池中指定位置(#2)的数据已经是个oop类型,说明BBB的class已经被加载并解析过,则直接通过(klassOop)entry.get_oop()返回klassOop;否则表示***次使用BBB,需要解析BBB的符号引用,并加载BBB的class类,生成对应的instanceKlass对象,并更新constant pool中对应位置的符号引用;
3、klass->check_valid_for_instantiation可以防止抽象类被实例化;
4、klass->initialize实现如下:

如何用JVM源码分析Java对象的创建过程

如果BBB的instanceKlass对象已经初始化完成,则直接返回;否则通过initialize_impl方法进行初始化,整个初始化算法分成11步,具体实现如下:

step1

如何用JVM源码分析Java对象的创建过程

通过ObjectLocker在初始化之前进行加,防止多个线程并发初始化。

step2

如何用JVM源码分析Java对象的创建过程

如果当前instanceKlass处于being_initialized状态,且正在被其它线程初始化,则执行ol.waitUninterruptibly等待其他线程完成后通知。

step3

如何用JVM源码分析Java对象的创建过程

如果当前instanceKlass处于being_initialized状态,且被当前线程初始化,则直接返回。
其实对于这个step的处理我有疑问,什么情况会走到这一步?经过RednaxelaFX大大提点,如下情况会执行step3:
例如A类有静态变量指向一个new B类实例,B类里又有静态变量指向new A类实例,这样外部用A时要初始化A类,初始化过程中又要触发B类初始化,B类初始化又再次触发A类初始化。

step4

如何用JVM源码分析Java对象的创建过程

如果当前instanceKlass处于fully_initialized状态,说明已经初始化完成,则直接返回;

step5

如何用JVM源码分析Java对象的创建过程

如果当前instanceKlass处于initialization_error状态,说明初始化失败了,抛出异常。

step6

如何用JVM源码分析Java对象的创建过程

设置当前instanceKlass的状态为 being_initialized;设置初始化线程为当前线程。

如何用JVM源码分析Java对象的创建过程

如果当前instanceKlass不是接口类型,并且父类不为空,且还未初始化,则执行父类的初始化。

step8

如何用JVM源码分析Java对象的创建过程

通过this_oop->call_class_initializer方法执行静态块代码,实现如下:

如何用JVM源码分析Java对象的创建过程

this_oop->class_initializer()可以获取静态代码块入口,最终通过JavaCalls::call执行代码块逻辑,再下一层就是具体操作系统的实现了。

step9

如何用JVM源码分析Java对象的创建过程

如果初始化过程没有异常,说明instanceKlass对象已经初始完成,则设置当前instanceKlass的状态为 fully_initialized,***通知其它线程初始化已经完成;否则执行step10 and 11。

step10 and 11

如何用JVM源码分析Java对象的创建过程

如果初始化发生异常,则设置当前instanceKlass的状态为 initialization_error,并通知其它线程初始化发生异常。

如果instanceKlass初始化完成,klass->allocate_instance会在堆内存创建instanceOopDesc对象,即类的实例化;

instanceOopDesc

当在Java中new一个对象时,本质是在堆内存创建一个instanceOopDesc对象。

如何用JVM源码分析Java对象的创建过程

instanceOopDesc在实现上继承自oopDesc,其中oopDesc定义如下:

如何用JVM源码分析Java对象的创建过程

当然,这只是 oopDesc的部分实现,oopDesc包含两个数据成员:_mark 和 _metadata。
1、_mark是markOop类型对象,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向线程ID、偏向时间戳等等,占用内存大小与虚拟机位长一致,更具体的实现可以阅读 《java对象头的HotSpot实现分析》
2、_metadata是一个联合体,其中wideKlassOop和narrowOop都是指向InstanceKlass对象的指针,wide版是普通指针,narrow版是压缩类指针(compressed Class pointer)

instanceOopDesc对象的创建过程

如何用JVM源码分析Java对象的创建过程

instanceOopDesc对象通过instanceKlass::allocate_instance进行创建,实现过程如下:
1、has_finalizer判断当前类是否包含不为空的finalize方法;
2、size_helper确定创建当前对象需要分配多大内存;
3、CollectedHeap::obj_allocate从堆中申请指定大小的内存,并创建instanceOopDesc对象,实现如下:

如何用JVM源码分析Java对象的创建过程

如果当前类重写了finalize方法,且非空,需要把生成的对象封装成Finalizer对象并添加到  Finalizer链表中,对象被GC时,如果是Finalizer对象,会将对象赋值到pending对象。Reference  Handler线程会将pending对象push到queue中,Finalizer线程poll到对象,先删除掉Finalizer链表中对应的对象,然后再执行对象的finalize方法;

关于如何用JVM源码分析Java对象的创建过程就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

--结束END--

本文标题: 如何用JVM源码分析Java对象的创建过程

本文链接: https://www.lsjlt.com/news/287125.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何用JVM源码分析Java对象的创建过程
    这篇文章将为大家详细讲解有关如何用JVM源码分析Java对象的创建过程,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。基于HotSpot实现对Java对象的创建过程进行深入分析。定义两个简单的...
    99+
    2023-06-17
  • 基于java构造方法Vector创建对象源码分析
    (注意:本文基于JDK1.8)  前言 Vector是线程安全的动态数组类,提供4个创建Vector对象的构造方法,接下来我们逐个分析每个创建Vector对象的构造方法 ...
    99+
    2022-11-12
  • SpringBoot启动流程入口参数创建对象源码分析
    目录入口探讨primarySource参数args参数创建对象1、推断web应用类别2、加载Spring应用上下文初始化3、加载Spring应用事件监听器4、推断应用引导类入口 这...
    99+
    2023-05-14
    SpringBoot 启动参数创建 SpringBoot 启动
  • spring是如何注入对象的和bean创建过程分析
    首先需要知道一个大致实现● 这个注入过程肯定是在 BeanPostProcessor 中实现的●spring 是在 beanFactory.getBean 进行 bean 实例化的,即懒加载● 根据第二条,也就是说在 getBean 的时候...
    99+
    2019-05-21
    java教程 spring 注入对象 bean
  • 如何分析Java创建线程中的代码
    如何分析Java创建线程中的代码,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Java创建线程经常在我们的编码中出现,当我们在使用的时候会有不少的问题困扰着我们...
    99+
    2023-06-17
  • 二维码的Java对象:如何创建和使用?
    二维码已成为了现代生活中不可或缺的一部分。它们可以在各种场合中使用,比如支付、购物、广告等等。在Java中,我们可以使用Qrcode库来创建和使用二维码对象。 一、创建二维码对象 首先,我们需要在项目中引入Qrcode库。在maven项目中...
    99+
    2023-08-29
    二维码 对象 path
  • 如何用Play源代码分析Server启动过程
    这期内容当中小编将会给大家带来有关如何用Play源代码分析Server启动过程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Play是个Rails风格的Java Web框架。如何调试请看此处。以下进入正题...
    99+
    2023-06-17
  • 如何用Java多线程在mail中创建Thread对象
    这篇文章将为大家详细讲解有关如何用Java多线程在mail中创建Thread对象,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。Java多线程有很多的知识需要我们学习,在学习的时候还是需要我们...
    99+
    2023-06-17
  • 如何用源码分析Struts2请求处理及过程
    这期内容当中小编将会给大家带来有关如何用源码分析Struts2请求处理及过程,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1.1 Struts2请求处理1. 一个请求在Struts2框架中的处理步骤:a)...
    99+
    2023-06-17
  • Java学习笔记:如何使用对象创建和解码二维码?
    随着智能手机等移动设备的普及,二维码已经成为了一种常见的信息传递方式。在Java中,我们可以使用对象创建和解码二维码。本篇文章将会介绍如何使用对象创建和解码二维码。 创建二维码 在Java中,我们可以使用QRCodeWriter类来创建二...
    99+
    2023-08-13
    学习笔记 对象 二维码
  • 如何进行java面向对象编程原理的分析
    这期内容当中小编将会给大家带来有关如何进行java面向对象编程原理的分析,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。Java 的核心是面向对象编程。事实上,所有的Java 程序都是面向对象的,你别无选择...
    99+
    2023-06-03
  • Java对象的内存分配过程是如何保证线程安全的
    本篇内容介绍了“Java对象的内存分配过程是如何保证线程安全的”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在开始进入正题之前,请允许我问一...
    99+
    2023-06-16
  • 如何使用Go语言和Apache创建高效的二维码对象?
    二维码的应用已经越来越广泛。我们可以在各种场景下看到它的身影,例如在商业广告宣传、商品防伪、门票验证等方面。在这篇文章中,我们将介绍如何使用Go语言和Apache创建高效的二维码对象。 在开始前,我们需要先了解一下二维码的生成原理。二维码是...
    99+
    2023-09-01
    二维码 apache 对象
  • 如何利用Go语言和Apache创建可靠的二维码对象?
    二维码(QR Code)是一种广泛应用于商业领域的编码形式。它可以存储大量的信息,例如网址、电话号码、电子邮件地址等。在本文中,我们将介绍如何利用Go语言和Apache创建可靠的二维码对象。 一、Go语言和Apache简介 Go语言是由Go...
    99+
    2023-08-31
    二维码 apache 对象
  • 如何在PHP中使用对象编程算法和函数创建高效的代码?
    PHP是一种流行的编程语言,被广泛应用于Web开发、应用程序开发等领域。在PHP中,使用对象编程算法和函数可以大大提高代码的可重用性和可维护性。本文将介绍如何在PHP中使用对象编程算法和函数创建高效的代码。 一、理解对象编程 对象编程是一种...
    99+
    2023-10-10
    对象 编程算法 函数
  • 如何在PHP中使用函数和对象编程算法创建更好的代码?
    PHP是一种流行的服务器端编程语言,它可以用来开发各种类型的Web应用程序。在PHP中,函数和对象编程算法是非常重要的,可以帮助开发人员创建更好的代码。在本文中,我们将介绍如何在PHP中使用函数和对象编程算法创建更好的代码。 一、函数编程 ...
    99+
    2023-10-10
    对象 编程算法 函数
  • 如何在 Python 中使用对象和二维码创建有趣的应用程序?这里有教程!
    Python 是一种非常流行的编程语言,具有广泛的应用领域。在 Python 中,我们可以利用对象和二维码创建有趣的应用程序。本文将介绍如何使用 Python 中的对象和二维码创建应用程序,并提供相关教程和演示代码。 1. 对象 在 Pyt...
    99+
    2023-09-04
    教程 对象 二维码
  • 如何在PHP中使用二维码框架对象来创建高质量的二维码?
    二维码已经成为了现代通讯中不可或缺的一部分,因为它们可以储存大量的信息并且可以在无需人工干预的情况下进行扫描。在PHP中,使用二维码框架对象创建高质量的二维码是非常容易的。这篇文章将会介绍如何在PHP中使用二维码框架对象来创建高质量的二维码...
    99+
    2023-07-31
    二维码 框架 对象
  • PHP、JavaScript 和 Apache:如何使用对象来创建可扩展的 Web 应用程序?
    Web 应用程序是现代互联网的核心。在这个数字化的时代,Web 应用程序的需求不断增长,使得开发人员需要更好的工具来满足业务需求和用户需求。PHP、JavaScript 和 Apache 是 Web 应用程序的三大核心技术,使用对象来创建...
    99+
    2023-08-19
    javascript 对象 apache
  • 如何通过 Python 对象响应框架构建出色的 Web 应用程序?
    Python 是一种非常流行的编程语言,拥有大量的第三方库和框架,其中 Flask 和 Django 是最流行的 Web 应用框架之一。而 Python 对象响应框架是一种新兴的 Web 框架,它可以帮助开发人员更快速地构建出色的 Web ...
    99+
    2023-10-03
    对象 响应 框架
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作