35

虚拟机系列 | JVM类加载机制

 4 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU4Njg0MzYwNw%3D%3D&%3Bmid=2247484904&%3Bidx=1&%3Bsn=da482e4543ad9716ab631cfe9c8c8a19
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一、类加载简介

类的加载机制是指把编译后的.class类文件的二进制数据读取到内存中,并为之创建一个java.lang.Class对象,用来封装类在元数据空间的数据结构。

r6NBnmB.png!mobile

类在JVM中的生命周期为:加载,连接,初始化,使用,卸载。不过这里只重点描述加载,连接,初始化这三个过程。

二、加载过程

基于一张图看类加载子系统的细节流程:

FvQZvu3.png!mobile

1、加载阶段

过程描述

加载阶段需要完成以下三个过程:

  • 通过类的全限定名来获取其定义的二进制字节流;

  • 将字节流所代表的静态存储结构转化为云数据空间的运行时数据结构;

  • 在堆Heap中生成一个代表这个类的java.lang.Class对象,作为对元数据空间中这些数据的访问入口;

类加载器

  • 引导类加载器

Bootstrap-ClassLoader基于C/C++实现,负责加载Java的核心类库JAVA_HOME\jre\lib\rt.jar,该加载器不继承自ClassLoader抽象类,并且只加载包名为java、javax、sun等开头类,一次保证对核心源码的保护。

  • 扩展类加载器

Extension-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,派生于ClassLoader抽象类,从java.ext.dirs系统变量指定的路径中的加载类库,或者JDK安装目录jre\lib\ext目录下加载。

  • 系统类加载器

Application-ClassLoader,基于Java语言,由sun.misc.Launcher$ExtClassLoader实现,它负责加载环境变量ClassPath指定的类库,如果在应用程序中没有自定义类加载器,一般情况下作为程序中默认的类加载器。

2、连接阶段

验证

目的在于确保Class文件的字节流中包含的信息符合当前虚拟机的要求,保证加载类的正确性,不会危害虚拟机自身的安全,主要包括四种检验动作:

  • 文件格式验证:验证字节流是否符合Class文件格式的规范;

  • 元数据验证:确保其描述的信息符合Java语言规范的要求;

  • 字节码验证:确定程序语义是符合逻辑的;

  • 符号引用验证:确保解析动作能正确执行。

准备

为类的静态变量分配内存,并初始化为默认值,这时候进行内存分配的仅包括类变量(static)修饰,不包括(final-static)修饰的,这里也不会为实例变量分配初始化,实例变量会随着对象一块分配到Java堆中。

解析

将常量池中的符号引用转换为直接引用的过程,直接引用就是直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄。解析主要针对类或接口、字段、类方法、接口方法、方法类型等,解析的动作实际是会随着JVM在执行完初始化之后再执行的。

3、初始化阶段

执行类构造器clinit ()方法的过程,该方法不需要自定义,是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中的语句合并而来,Jvm要保证clinit ()方法在多线程访问下的安全性。

三、机制策略

1、双亲委派模式

nIjIBvf.png!mobile

类加载器收到了类加载的请求时,不会自己先去尝试加载这个类,而是把请求委托给父加载器去执行;

如果父加载器还存在父类加载器,则依次向上委托,因此类加载请求最终都应该被传递到顶层的启动类加载器中;

如果父类加载器可以完成类加载请求,就直接成功返回,只有当父加载器在无法完成该加载,子加载器才会尝试自己去加载该类;

2、沙箱安全机制

假设自定义一个类名为String且所在包为java.lang,在使用引导类加载器加载时会先加载JDK中的String类,因为这个类本来是属于jdk的,后面再次出现String类就会报错,以此保证源代码不被恶意篡改,这就是沙箱安全机制。

四、源代码地址

GitHub·地址
https://github.com/cicadasmile/java-base-parent
GitEE·地址
https://gitee.com/cicadasmile/java-base-parent

uaE36bV.png!mobile


Recommend

  • 28
    • www.cnblogs.com 4 years ago
    • Cache

    JVM类加载机制小结

    这篇文章我们关注一个问题:Java程序是怎么进入JVM并执行的? 经常写Java程序的小伙伴应该都听说过类加载机制,在《深入理解Java虚拟机》里周老师已经讲的很清楚了,这篇随笔把之前的笔记以及一些总结重新梳理...

  • 39

    本文源码: GitHub·点这里 || GitEE·点这里 一、虚拟机简介 1、虚拟机概念...

  • 31
    • www.cnblogs.com 4 years ago
    • Cache

    玩命学JVM(二)—类加载机制

    前言 Java程序运行图: 上一篇 玩命学JVM...

  • 9
    • www.dynamic-zheng.com 4 years ago
    • Cache

    [JVM] JVM 是如何加载 Java 类的?

    [JVM] JVM 是如何加载 Java 类的? 2020-11-15 | 2020-11-22 ...

  • 13
    • www.justdojava.com 4 years ago
    • Cache

    JVM 是如何加载 Java 类的?

    JVM 是如何加载 Java 类的? 发表于...

  • 7
    • yuanfentiank789.github.io 4 years ago
    • Cache

    Android 面试必备 - JVM 及 类加载机制

    java 内存分区 参考博客 JVM所管理的内存分为以下几个运行时数据区:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区。

  • 5
    • yuanfentiank789.github.io 4 years ago
    • Cache

    Jvm系列3—类的加载

    本文主要讲述虚拟机如何把 Class文件加载到内存的过程。校验、转换解析和初始化,最终形成可被虚拟机使用的Java类型,这就是虚拟机的类加载机制。类型的加载、连接和初始化都是在程序运行期间完成,这样做的优劣势,如下: 优势:提高Java程序的灵...

  • 15

    本博客主要参考周志明老师的《深入理解Java虚拟机》第三版 欢迎指出文章的不足之处;更多内容请点进爱敲代码的小游子查看

  • 9
    • www.cnblogs.com 4 years ago
    • Cache

    JVM系列(二):jvm加载java入口main

    上一篇粗略讲了下jvm的启动过程,但很多路子还没跑通。其中非常核心的,加载vm的过程。这个可以在hotspot中找到端倪。但java启动,还有几个线程可以看看。 1. main类的载入 在java.c中,我们可以看到一个JavaMain方法,不知从何...

  • 3
    • duanguangguang.github.io 4 years ago
    • Cache

    JVM类加载机制

    JVM类加载机制 发表于 2020-04-18 ...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK