Ezio's Blog
Posts Categories Tags Music Mood About
Ezio's Blog· Light
☰ Menu
Posts Categories Tags Music Mood About
Expand all Back to top Go to bottom

JVM 类加载过程

Author: Ezio Date: December 30, 2019  14:53:46 Category: Java

JVM 类加载过程

在Java代码中,类型的加载、连接与初始化过程都是在程序运行期间(Runtime)完成的。


**类的加载:**查找并记载类的二进制数据

**类的连接:**验证——确保被加载的类的正确性

​ 准备——为类的静态变量分配内存,并将其初始化为默认值

​ 解析——把类中的符号引用转换为直接引用

类的初始化:为类的静态变量赋予正确的初始化


类加载的过程:

  1. 加载:

    找到字节码文件,读取到内存中.类的加载方式分为隐式加载和显示加载两种。隐式加载指的是程序在使用new关键词创建对象时,会隐式的调用类的加载器把对应的类加载到jvm中。显示加载指的是通过直接调用Class.forName()方法来把所需的类加载到jvm中。

  2. 验证:

    验证此字节码文件是不是真的是一个字节码文件,毕竟后缀名可以随便改,而内在的身份标识是不会变的.在确认是一个字节码文件后,还会检查一系列的是否可运行验证,元数据验证,字节码验证,符号引用验证等.Java虚拟机规范对此要求很严格

  3. 准备:

    为类中static修饰的变量分配内存空间并设置其初始值为0或null.可能会有人感觉奇怪,在类中定义一个static修饰的int,并赋值了123,为什么这里还是赋值0.因为这个int的123是在初始化阶段的时候才赋值的,这里只是先把内存分配好.但如果你的static修饰还加上了final,那么就会在准备阶段就会赋值.

  4. 解析:

    解析阶段会将java代码中的符号引用替换为直接引用.比如引用的是一个类,我们在代码中只有全限定名来标识它,在这个阶段会找到这个类加载到内存中的地址

  5. 初始化:

    这个阶段就是对变量的赋值的阶段.

ps:同一个类,如果使用的是不同的类加载器加载的,那么最后使用instanceof会返回一个false

双亲委派机制:

向上委派向下加载

JVM的生命周期

JVM的生命周期大致分为以下三个阶段:

  • JVM实例的诞生

    当启动一个Java程序时,一个JVM实例就产生了,任何一个拥有 public static void main(String[] args) 函数的class都可以作为JVM实例运行的起点

  • JVM实例的运行

    main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程。java程序的初始线程 只就是运行main()的线程,这个线程是非守护线程,只要还有任何非守护线程还在运行,那么JVM就存活着

  • JVM实例的消亡

    当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程序也可以使用 java.lang.Runtime 类或者 java.lang.System.exit() 来退出


Java类的生命周期

当我们编写一个java的源文件后,经过编译会生成一个后缀名为class的文件,这种文件叫做字节码文件,只有这种字节码文件才能够在java虚拟机中运行,**java类的生命周期就是指一个class文件从加载到卸载的全过程。**一个java类的完整的生命周期会经历加载、连接、初始化、使用、和卸载五个阶段,当然也有在加载或者连接之后没有被初始化就直接被使用的情况,大致过程如下图所示:


Java程序对类的使用方式分为两种:

1.主动使用

2.被动使用

所有的Java虚拟机实现必须在每个类或者接口被Java程序“首次主动使用”才能初始化他们。


主动使用(七种):

1.创建类的实例

2.访问某个类或者接口的静态变量,或对该静态变量赋值。(静态变量的取值或者赋值)getstatic、putstatic(助记符)

3.调用类的静态方法。invokestatic

4.反射(如 Class.forName (“com.ylw.Test”))。

5.初始化一个类的子类

6.Java虚拟机启动时被标名为启动类的类(包含main方法)。

7.JDK1.7开始提供的动态语言支持:java.lang.invok.MethodHandle 实例的解析结果 REF_getStatic, REF_putStatic, REF_invokeStatic 句柄对应的类没有初始化则初始化。

ps: 除了以上七种情况,其他使用java类的方式都被看做是对类的被动使用,都不会导致类的初始化。


Author: Ezio

Permalink: https://ezioy.cn/2019/12/30/JVM%E7%B1%BB%E5%8A%A0%E8%BD%BD%E8%BF%87%E7%A8%8B/

License: Copyright (c) 2019 CC-BY-NC-4.0 LICENSE

Slogan: Nothing is true,Everything is permitted

Tag(s): # Java
back · home
观《互联网是我们时代的集体健忘症》有感 Redis数据类型
Ezio © 2019 - 2026 | Powered by Hexo & Chic | 访客数量:   浏览次数: | 渝公网安备50011302222043 | 渝ICP备2023013933号-1