new对象时Java虚拟机的工作流程解析

周日的上午,笔者像往常一样盯着电脑发呆,想起昨晚的梦中,一个身着西装的面试官问道:你知道new一个对象时,Java虚拟机是怎么工作的吗?
我:
在这里插入图片描述
没办法,那今天就复习一下好了。
**加粗样式**

类的生命周期分为7个阶段加载、验证、准备、解析、初始化、使用、卸载

下图是笔者自定义的类。

class Man {
    String s;
    public Man(String string){
        s = string;
    }
}

public class Solution{
    public void test(){
        Man a = new Man("abc");
        return;
    }
}

利用jclasslib工具可以看到test方法的字节码文件。

 0 new #7 <test/Man>
 3 dup
 4 ldc #9 <abc>
 6 invokespecial #11 <test/Man.<init>>
 9 astore_1
10 return

下面结合字节码文件对该类的生命周期进行分析。

加载:加载阶段发生在第一步之前,主要作用有:

  • 将类的字节码载入方法区运行时常量池中,内部采用 C++ 的 instanceKlass 描述 java 类,它的重要 field 有:

    • _java_mirror 即 java 的类镜像,例如对 String 来说,就是 String.class,作用是把 klass 暴露给 java 使用

    • _super 即父类

    • _fields 即成员变量

    • _methods 即方法

    • _constants 即常量池

    • _class_loader 即类加载器

    • _vtable 虚方法表

    • _itable 接口方法表

  • 中生成一个代表这个类的java.lang.Class对象(比如样例中即为man.Class对象),作为方法区这个类的各种数据的访问入口。

验证:验证阶段同样发生在第一步之前,主要作用为验证类是否符合 JVM规范,安全性检查。(注意验证阶段往往和加载阶段同时进行)

准备:当一个类验证通过时,虚拟机就会进入准备阶段。在这个阶段,虚拟机就会为这个类分配相应的内存空间,并设置初始化值。

解析:将常量池中的类、接口、字段、方法符号引用转为直接引用,比如类中定义了一个方法,该方法一开始作为符号引用存储于常量池中,解析后可在常量池中直接定位到该方法在内存中的真实地址。(注意:《Java虚拟机规范》并未规定解析阶段发生的具体时间,只要求在invokespecial等17个用于操作符号引用的字节码指令之前,对它们使用的符号引用进行解析,因此,解析有时发生在初始化阶段之后

注意:验证准备解析三个阶段统称为链接阶段,其中验证阶段往往与加载阶段同时进行。

初始化:是类加载过程的最后一个步骤,直到初始化阶段,Java虚拟机才真正开始执行类中编写的程序代码

之后开始执行字节码文件中的内容。

下面从字节码文件入手,分析整个过程。

首先是

new #7 <test/Man>

在该线程的虚拟机栈的操作数栈压入了指向之前分配的man的实例的内存的地址供任何下面的操作来调用。

dup

复制操作数栈的栈顶值,并将其压入栈顶,也就是说此时操作数栈上有连续相同的两个对象地址

ldc #9 <abc>

将String型常量值"abc"从常量池中推送至栈顶。

//在该条字节码指令之前解析常量池中的#11即可
invokespecial #11 <test/Man.<init>>

调用类的构造方法。(注意:这里将之前压入操作数栈的"abc"取出来作为实参传入了类的构造方法,接着从操作数栈顶弹出一个实例对象的引用,即将对象创建在之前入栈的对象地址上)

astore_1

从操作数栈顶取出 man 对象的引用并存到局部变量表。(之前连续两次存入了同一个对象地址,现在取出的是第二个

return

最后由return指令结束方法。

以上便是全部的类加载过程,如有纰漏,欢迎指正。
在这里插入图片描述

  • 9
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值