jvm学习笔记(如果有不对和不足的地方,请指出)

目录

类的加载

类加载器

双亲委派机制

类的主动使用和被动使用

运行时数据区内部结构

程序计数器

虚拟机栈

栈的储存结构和运行原理

栈帧的内部结构


类的加载

图示

类的加载:

  • 将外部的字节码文件加载到虚拟机中,并且储存在方法区内。

  • 通过类的全限定类名来获取此类的二进制字节流。

  • 将这个字节码文件流所代表的静态结构转化为方法区的运行时结构。

  • 在内存中生成一个这个类的java.lang.class对象,作为方法区这个类的各种数据的访问入口。

链接:

  • 验证

    • 确保加载类的正确性

  • 准备

    • 为类变量在方法区中分配内存

    • 为类变量设置初始值

      • 注意

      • 实列变量的初始化不在准备阶段分配内存

      • 实列变量是随着对象实列化随着对象一起分配在内存中

  • 解析

    • 将常量池内的符号引用转化为直接引用

初始化

初始化是指为类的静态变量赋值

  • 在声明变量时指定初始值

  • 使用静态代码块为变量指定初始值

具体的流程是

  • 生成类的构造器<clinit>

    • 它是由类变量和静态代码块构成。

      • 注意

      • init是为对象初始化,而<clinit>是为类变量赋值

    • 执行<clinit>方法

类加载器

类加载器

  • 引导类加载器(获取不到,不是用java语言写的)

    • 主要加载的是jvm自身需要的类

    • 只能加载包名为java、javax、sun开头的类

  • 扩展类加载器

    • 负责加载<JAVA_HOME>/lib/ext下的类库

  • 系统类加载器

    • 负责加载系统类路径java -classpath-D java.class.path 指定路径下的类库,也就是我们经常用到的classpath路径

双亲委派机制

双亲委派机制是当前类加载器不要进行处理而是由父类进行处理,如果父类处理不了则再子类进行处理

作用:

  • 防止类的重复加载

  • 保护程序的安全,防止api被篡改

类的主动使用和被动使用

jvm规定了以下6种为主动使用

  • 通过new 关键字会导致类的初始化

  • 访问类的静态变量

  • 访问类的静态方法

  • 对某个类进行反射操作

  • 初始子类会导致父类的初始化

  • 启动类:也就是类的main方法执行会导致该类的初始化

除了上述的六种方式会导致类的主动使用,其它的会导致类的被动使用

运行时数据区内部结构

  • 程序计数器

  • 堆区

  • 方法区

    • 本地方法栈

    • 虚拟机栈

其中堆区和方法区是线程共享的,而程序计数器,本地方法栈、虚拟机栈是线程私有的。

程序计数器

程序计数器又叫pc计数器(并不是物理意义上的pc寄存器jvm的pc寄存器是对物理pc基础器的抽象模拟),它储存的是下一条即将执行的字节码储存地址。

  • 作用

    • 因为CPU需要不停的切换各个线程,这时候切换回来以后,就得知道接着从哪开始继续执行。JVM的字节码解释器就需要通过PC寄存器的值来明确下一条应该执行什么样的字节码指令。

  • PC寄存器为什么会设置线程私有

    • 为了能够准确地记录各个线程正在执行的当前字节码指令地址,最好的办法自然是为每一个线程都分配一个PC寄存器,这样一来各个线程之间便可以进行独立计算,从而不会出现相互干扰的情况。

虚拟机栈

内存中栈和堆的区别

栈是运行时的单位,而堆是储存的单位,栈解决了程序证明执行,堆解决的是数据储存问题,数据怎么放,放在哪里。

 

每个线程都有一个虚拟机栈,虚拟机栈内部保存着一个个栈帧,一个栈帧就是一个方法(虚拟机栈是线程私有的)

生命周期

生命周期和线程一致,线程结束了,生命周期也就结束了。

作用

  • 它保存方法的局部变量(八种基本数据类型和对象的引用),部分结果,并且参与方法的调用和返回。

栈的特点

jvm对于栈的操作只用入栈和初栈这两种,对于栈来说不存在垃圾回收问题,但是存在栈溢出问题

栈溢出:

程序运行时,栈的大小小于当前线程运行时需要的栈的大小

栈的储存结构和运行原理

  • 栈是由栈帧构成,而一个栈帧对应一个方法。jvm对于java栈的操作只有两种,压栈和出栈。

  • 在一条栈帧中,一个时间点上只会有一个活动栈帧,即当前活动的栈帧的是有效的,这个栈帧是当前栈帧。对于的方法就是当前方法,定义这个方法的类就是当前方法。

  • 执行引擎运行的字节码是对当前栈帧进行操作。

  • 如果该方法调用其他方法,就会创建调用方法的栈帧,放在栈顶成为新的当前栈。

  • 栈帧是线程私有的

  • .当前方法返回之际,当前栈帧会传回此方法的执行结果给前一个栈帧,接着虚拟机会丢弃当前栈帧,使得前一个栈帧重新成为当前栈帧

  • Java函数返回方式有两种,使用return或者抛出异常。不管哪种方式,都会导致栈帧被弹出。

栈的运行原理图

栈帧的内部结构

  • 局部变量表

  • 操作数栈

  • 动态链接

  • 方法返回地址

  • 一些附加信息

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值