Java虚拟机一记

执行Class文件的环境

虚拟机结构

虚拟机是执行Class文件的环境,通过类加载子系统加载进来,其一般包括:运行时数据区域、执行引擎(即时编译器、垃圾回收器)、本地库接口、本地方法库。

Class文件格式

此二进制格式文件独立于特定的硬件与操作系统。

任何语言,只要能被编译成Class文件,就可以被Java虚拟机识别并执行。

每一个Class文件中都对应着唯一的类或者接口的定义信息。包含的信息有:

  • 副、主版本号
  • 常量池计数器、常量池
  • 类和接口层次的访问标志
  • 接口计数器、接口表
  • 字段计数器、字段表
  • 方法计数器、方法表
  • 属性计数器、属性表

总之,通过已定规则,将类或接口的信息转换成Class文件格式。

类的生命周期

一般指:Java文件被加载到Java虚拟机内存中到从内存中卸载的过程。

大致如下:

  • 加载:查找并加载Class文件

  • 链接:包括验证、准备和解析

    验证:确保被导入类型的正确性

    准备:为类的静态字段分配字段,并用默认值初始化这些字段

    解析:虚拟机将常量池内的符号引用替换为直接引用

  • 初始化:将类变量出事为正确初始值

类加载子系统

有2种类加载器:系统加载器和自定义加载器。其中,系统加载器包括下面3种:

  • Bootstrap ClassLoader(引导类加载器)

    C/C++实现,加载指定的JDK的核心类库

  • Extensions ClassLoader(拓展类加载器)

    用于加载Java的拓展类

  • Application ClassLoader(应用程序类加载器)

运行时数据区域

  • 方法区

    线程共有

  • Java堆

    线程共有

  • Java虚拟机栈

    线程私有,有OOM,保存Java程序的栈帧

  • 本地方法栈

    线程私有,有OOM,保存Native程序的栈帧

  • 程序计数器

    线程私有,没有OOM,针对Java程序(Native程序不管)

对象的创建

通过new指令来完成一个对象的创建。有如下操作:

  • 判断对象对应的类是否加载、链接和初始化
  • 分配内存
  • 处理并发安全问题
  • 初始化分配到的内存空间
  • 设置对象头
  • 执行init方法进行初始化

对象的堆内存布局

  • 对象头

    Mark Word、元数据指针

    Mark Word:hash、age(对象的分代年龄)、biased_lock(偏向锁标识位)…

  • 实例数据

  • 对齐填充

oop-klass模型

用来描述Java对象实例的一种模型。

  • OOP(Ordinary Object Pointer)

    指的是普通对象指针,用来表示对象的实例信息。

  • klass

    用来描述元数据

垃圾标记算法

Java中的引用

  • 强引用

    GC时,不回收

  • 软引用

    GC时,不够用才回收

  • 弱引用

    GC时,遇到就回收

  • 虚引用

    GC时,遇到就回收,被回收时会收到一个系统通知。

引用计数法

iOS中Objective-C中使用,不能解决循环引用的问题。

根搜索算法

GC Roots
  • Java栈中引用的对象

  • 本地方法栈中JNI引用的对象

  • 方法区中运行时常量池引用的对象

  • 方法区中静态属性引用的对象

  • 运行中的线程

  • 由引导类加载器加载的对象

  • GC控制的对象

Java对象在虚拟机中的生命周期

  • 创建阶段(Created)

    分配空间——构造对象——构造方法

  • 应用阶段(In Use)

    至少有一个强引用,或者显示的使用软、弱、虚引用

  • 不可见阶段(Invisible)

    在程序中找不到对象的任何强引用。但对象仍可能被特殊的强引用GC Roots持有着,比如对象被贝蒂方法栈中JNI引用或运行中的线程引用等。

  • 不可达阶段(Unreachable)

    在程序中找不到对象的任何强引用,并且垃圾收集器发现对象不可达。

  • 收集阶段(Collected)

    垃圾收集器发现对象不可达,并且一记准备好要对对象的内存空间重新进行分配,如果对象重写了finalize方法,则会调用该方法。

  • 终结阶段(Finalized)

    在对象执行完finalize对象后仍然是不可达状态,或者没有重写此方法,则对象进入终结阶段,并等待被回收。

  • 对象空间重新分配阶段(Deallocated)

垃圾收集算法

标记-清除算法

  • 标记阶段

    标记处可以回收的对象

  • 清除阶段

    回收被标记的对象所占用的空间

缺点:效率低、易碎片。

复制算法

将内存空间分为2部分,每次只使用其中一个区域,在回收时,遍历当前使用区域,将存活的对象复制到另一个区域,然后将当前可回收对象进行回收。

缺点:利用率低。

标记-压缩算法

在标记可回收的对象后将所有存活的对象压缩到内存的一端,是它们紧凑地排列在一起,然后对边界以外的内存进行回收。

分代收集算法

对不同生命周期的对象采取不同的收集策略,根据生命周期长短将它们分别放到不同的区域,并在不同区域采用不同的收集算法。

Java堆区基于分代的概念,分为新生代与老年代,其中新生代还可以细分为Eden空间、From Survivor空间和To Survivor空间。

分代收集
  • Minor Collection:新生代垃圾回收

    当执行一次Minor Collection时,Eden空间的存活对象会被复制到To Survivor空间,在From Survivor空间存活的对象也会被复制到To Survivor空间。

    当对象存活年龄(经历一次GC涨一岁)超过阈值(-XX:MaxTenuringThreeshold)、To Survivor空间已满,则直接复制到老生代(晋级成功)。

    此时,Eden空间与From Survivor空间都会被清空,新生代的对象都在To Survivor空间中。

    最后,From Survivor空间与To Survivor空间互换位置,以确保To Survivor空间是空的。

  • Full Collection:老年代垃圾收回

    老生代会采用标记-压缩算法或标记-清除算法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值