美文网首页Android开发Android开发经验谈Android技术知识
细究JVM的生命周期、钩子函数、内存模型及类加载过程

细究JVM的生命周期、钩子函数、内存模型及类加载过程

作者: 程序老秃子 | 来源:发表于2022-05-21 20:48 被阅读0次

JVM

JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的

Java语言的一个非常重要的特点就是与平台的无关性;而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码;而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译

Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行;Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行;这就是Java的能够“一次编译,到处运行”的原因

JVM的生命周期

生命周期分为3个阶段,这三个阶段分别是: 初始化 、 运行中 、 销毁

初始化阶段

● 有4个钩子函数,触发条件是自动的 beforeCreate

● 组件即将创建,进行组件事件和生命周期的初始化

项目中一般不使用

● 有的开发者也会在这里进行数据请求created

组件创建完成

● 项目中:

1) 异步请求接口数据

2) 数据修改beforeMount

● 组件即将挂载

● 判断根实例组件是否有el选项,如果没有,那么手动挂载,判断根实例组件中的其他子组件是否有template选项,如果没有,那么使用outerHTML插入

● 项目中:

1) 异步请求接口数据

2) 数据修改mounted

● 组件挂载结束

● 使用真实DOM替换VDOM

● 项目中

1) 异步请求接口数据

2) 数据修改

3) 真实DOM操作可以了( Vue一般情况下不要直接操作真实DOM, 一般可以进行第三方库的实例化(静态数据渲染来的) )

总结: 初始化过程中在项目中使用

● 数据请求:created

● DOM操作: mounted

● 数据修改: beforeMount created mounted

运行中阶段

● 有2个钩子函数 : 触发条件是: 当data选项中的数据发生改变时 beforeUpdate

● 内部操作 : vdom生成和diff的对比 updated

● Rdom已经生成,可以进行异步数据请求得到的dom渲染的第三方库实例化 销毁阶段: 有2个钩子函数 beforeDestory: 组件即将销毁,准备调用 $destroy() 方法

● destoryed: 组件销毁结束

这两个钩子函数没有什么区别,功能很相似

● 项目中:

● 这两个钩子函数都可以用来做善后,把一些计时器,第三方库实例化出来的实例

组件销毁的两种方式

● 使用$destroy()方法(内部销毁)

● 缺点: 会将组件的模板也保留下来

● 使用开关销毁(外部销毁)

● v-if 这种类型的销毁不会留有模板

有一个钩子函数可以不写,这个钩子函数就是 render 函数

名词解释

钩子函数:

● 钩子函数就是options配置项中的一个方法,在特定的触发条件( 时机 )下会自动触发

● 除了根实例组件以外,其他的组件中的数据项 data 必须是一个函数,而且这个函数必须返回一个对象

为什么是函数呢?

● 原因:我们希望组件的数据是独立的,有一定作用域的

为什么返回值是对象?

● 原因: 是为了符合数据驱动原理设计,让observer将data选项中的数据设置 getter 和 setter

JVM内存模型

程序的运行最为重要的一块区域就是运行时数据区,其中运行时数据区可以分为如下几个子区域:

程序计数器

程序计数器是用于存放下一条指令所在单元的地址的地方

● 程序执行必须知道指令(计算机要通过指令才能执行),此时就需要从程序计数器中读取即将执行的指令的地址,通过这个地址就可以得到指令从而执行

● 比如线程即将执行一个Java方法,此时要先从程序计数器中取得即将执行的虚拟机字节码指令的地址。

虚拟机栈

● 该区域是线程私有的,虚拟机栈的生命周期和线程相同,在执行一个Java方法的时候会在该区域创建一个栈帧,栈帧用来保存局部变量表(在方法中定义的变量或者方法的参数都是方法的局部变量)、动态链接、方法出口、操作数栈等等信息

● 其实每个方法从执行到执行完毕就是一个入栈与出栈的过程。当入栈的速度大于出栈的速度的时候会出现栈内存溢出( Exception in thread "main" java.lang.StackOverflowError)。

本地方法栈

本地方法栈和虚拟机栈的作用很相似,不同点是虚拟栈是为Java方法服务的

● 本地方法栈是为native方法服务的(这种本地方法是没有方法体的,可以算是一个抽象方法,具体的实现是本地操作系统的c语言写的一些函数库中的方法实现的)

● 堆是运行时数据区中最大的一块子区域

● 创建的实例对象和数组都需要在堆内存开辟空间,堆空间是线程共享的区域,该区域也是gc (垃圾回收)重要从狸的一个区,所以堆又被称为“GC堆”。

方法区

● 永久代实现了方法区,永久代是在JDK1.8之前出现的概念

● 在JDK1.8开始就没有了永久代,而是使用了元空间代替了。

● 方法区也是一块线程共享的区域,该区域主要保存的是已经加载到jvm 中的类的信息、常量、静态变量等等

类加载过程

当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化;如果没有意外,JVM将会连续完成3个步骤,所以有时也把这3步骤统称为类加载或类初始化

类被加载到 JVM 开始,到卸载出内存,整个生命周期]如图:

加载

● 通过类名(地址)获取此类的二进制字节流

● 将这个字节流所代表的静态存储结构转换为方法区(元空间)的运行时结构

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

链接

就是将已经读入内存的类的二进制数据合并到JVM运行时环境中去,包含以下步骤:

验证

● 检验被加载的类是否有正确的内部结构,并和其他类协调一致

准备

● 准备阶段则负责为类的静态属性分配内存,并设置默认初始值;不包含final修饰的static实例变量,在编译时进行初始化。不会为实例变量初始化

解析

● 将类的二进制数据中的符号引用替换成直接引用。

初始化

类什么时候初始化?

● 创建类的实例,new对象

● 访问某个类或接口的静态变量,或者对该静态变量赋值

● 调用类的静态方法

● 反射(Class.forName(" "))

● 初始化一个类的子类(首先会初始化子类的父类)

● JVM启动时标明的启动类,即文件名和类名相同的那个类

● 注意:对于一个final类型的静态变量,如果该变量的值在编译时就可以确定下来,那么这个变量相当于“宏变量”。Java编译器会在编译时直接把这个变量出现的地方替换成它的值,因此即使程序使用该静态变量,也不会导致该类的初始化

● 反之,如果final类型的静态Field的值不能在编译时确定下来,则必须等到运行时才可以确定该变量的值,如果通过该类来访问它的静态变量,则会导致该类被初始化。

类的初始化顺序

对static修饰的变量或语句块进行赋值

● 如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

● 如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

● 顺序是:父类static -> 子类static -> 父类构造方法 -> 子类构造方法

JVM自身独特的优点

HotSpot(Java 虚拟机),是较新的Java虚拟机技术,用来代替JIT(just-in-time compilation,及时编译)技术,可以大大提高Java运行的性能。Java原先是把源代码编译为字节码在虚拟机执行,这样执行速度较慢。而该技术将常用的部分代码编译为本地(原生,native)代码,这样显著提高了性能

对于初学者来说,尽管Hotspot有些神秘,但是性能方面它确实很棒,因为动态建模(dynamic profiling)是优良性能的捷径。HotSpot从运行应用中采样数据,从而可以优化代码,进而得到良好性能;它相当于以模仿人工的方法进行优化

在程序运行的开始,Java代码仍然解释执行,但HotSpot引擎开始进行采样(Profiling)。HotSpot引擎可以集中精力来对HotSpot代码进行深度优化,从而使这部分代码的执行更加迅捷。因此当HotSpot优化时,它为优化设立了一层保护来确保优化的基本原理有效;但当这层保护失效时,优化就会很慢

尾述

技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面

Android 架构师之路还很漫长,与君共勉

PS:有问题欢迎指正,可以在评论区留下你的建议和感受; 欢迎大家点赞评论,觉得内容可以的话,可以转发分享一下

相关文章

  • 细究JVM的生命周期、钩子函数、内存模型及类加载过程

    JVM JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,...

  • 类加载机制

    JVM类加载机制 类加载子系统 类加载过程 类从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期包括:...

  • JVM总括四-类加载过程、双亲委派模型、对象实例化过程

    JVM总括四-类加载过程、双亲委派模型、对象实例化过程 目录:JVM总括:目录 一、 类加载过程 类加载过程就是将...

  • Java虚拟机

    JVM 组成部分 类加载器 执行引擎 内存区 本地方法调用 类加载器 双亲委派模型 类的加载过程采用双亲委派机制,...

  • 《32个Java面试必考点》学习笔记之四------JVM

    JVM知识点汇总知识点详解JVM内存模型栈本地方法栈程序计数器堆方法区JMM与内存可见性类加载与卸载加载过程加载机...

  • 《每日一面》劝退第一题

    问:JVM如何加载一个类的过程,双亲委派模型中有哪些方法? 答:   类从被加载到虚拟机内存中开始,到卸载出内存为...

  • JVM系列:(八)JVM内存模型

    原文链接:JVM系列:(八)JVM内存模型 一 运行时数据区域 类加载器加载的class字节码保存到JVM内存的方...

  • JAVA微服务技术栈相关 知识点梳理

    JVM jvm作为底层支撑,需要了解的有: 其中重点为类加载器与内存模型。类加载器中,主要自定义类加载器,加载自定...

  • JVM

    JVM组成 jvm由类加载器+内存+执行引擎 JVM内存区域 堆 线程共享 存储对象 虚拟机栈 线程私有,生命周期...

  • JVM

    1.Java对象创建的过程? 类加载检查、分配内存、初始化零值、设置对象头、执行 方法。 2.JVM内存模型 / ...

网友评论

    本文标题:细究JVM的生命周期、钩子函数、内存模型及类加载过程

    本文链接:https://www.haomeiwen.com/subject/zjfhprtx.html