首页 > 其他分享 >类加载机制

类加载机制

时间:2022-11-15 21:36:42浏览次数:48  
标签:初始化 Java ClassLoader 该类 机制 Class 加载

类的生命周期

首先我们先看类的生命周期

类的加载过程包含了加载、验证、准备、解析、初始这五个阶段,其中除了解析阶段其他四个阶段的发生顺序都是确定的,因为解析阶段在某些情况下会在初始阶段之后开始,同时这些阶段都是按顺序开始的不是按顺序进行或结束,因为这些阶段通常都是互相交叉的混合进行。以下为类的生命周期

加载->验证->准备->解析->初始化->使用->卸载 (验证->准备->解析这三个可概括为连接阶段)

在类的的加载阶段,虚拟机需要完成三件事:1、 通过一个类的全限定名来获取其定义的二进制字节流。2、将这个字节流所代表的金泰存储结构转化为方法区的运行时数据结构。3、Java堆中生成一个代表这个类的Java.lang.Class对象,作为对方法区中这些数据的访问入口。

类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误(LinkageError错误)如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。

连接阶段:

首先进行验证,确保当前Class文件的字节流信息是否符合当前虚拟机的要求分为:文件格式验证、元数据验证、字节码验证、 符号引用验证。然后进行准备阶段开始正式为类的变量(仅包括类变量static,不包含实例变量,实例变量会在对象实例化时一起分配到Java堆中)分配内存并设置变量初始值(零值非代码中的数值)的阶段,这些内存在方法区中分配。开始解析,将常量池中的常量引用替换为直接引用。

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

初始化有以下步骤:如果这个类还没有被加载和连接则先进行加载和连接;如果该类 的父类还没有被初始化,则先初始化其父;如果该类中有初始化语句则先依次执行类中的初始化语句。

由此也可得出类的初始话时机,创建类的实例时(new);访问某个类或接口的静态变量或对该静态变量赋值时;调用类的静态方法时;反射(Class.forname("com.XXX.XXX"));初始化某个类的子类时;Java虚拟机启动时被标记为启动类时

使用:类访问方法区内的数据结构的接口,对象时Heap区(堆区)的数据。

最后卸载阶段:执行了System.exit()方法时;程序正常结束时;程序执行过程中遇到了异常或错误导致异常终止;由于操作系统出翔错误而导致java虚拟机进程终止;

类加载器、jvm加载机制:

 

再java程序员的眼中类加载器主要分为三种;

启动类加载器: Bootstrap ClassLoader,负责加载存放在JDK\jre\lib(JDK代表JDK的安装目录,下同)下,或被-Xbootclasspath参数指定的路径中的,并且能被虚拟机识别的类库(如rt.jar,所有的java.*开头的类均被Bootstrap ClassLoader加载)。启动类加载器是无法被Java程序直接引用的。

扩展类加载器: Extension ClassLoader,该加载器由sun.misc.Launcher$ExtClassLoader实现,它负责加载JDK\jre\lib\ext目录中,或者由java.ext.dirs系统变量指定的路径中的所有类库(如javax.*开头的类),开发者可以直接使用扩展类加载器。

应用程序类加载器: Application ClassLoader,该类加载器由sun.misc.Launcher$AppClassLoader来实现,它负责加载用户类路径(ClassPath)所指定的类,开发者可以直接使用该类加载器,如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。

类的加载:

  1. 命令行启动应用时候由JVM初始化加载

  2. 通过Class.forName()方法动态加载

  3. 通过ClassLoader.loadClass()方法动态加载

Class.forName()和ClassLoader.loadClass()区别?

  • Class.forName(): 将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块;

  • ClassLoader.loadClass(): 只干一件事情,就是将.class文件加载到jvm中,不会执行static中的内容,只有在newInstance才会去执行static块。

  • Class.forName(name, initialize, loader)带参函数也可控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象 。

JVM类加载机制:

  • 全盘负责,当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入

  • 父类委托,先让父类加载器试图加载该类,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类

  • 缓存机制,缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区寻找该Class,只有缓存区不存在,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效

  • 双亲委派机制, 如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

双亲委派机制过程?

  1. 当AppClassLoader加载一个class时,它首先不会自己去尝试加载这个类,而是把类加载请求委派给父类加载器ExtClassLoader去完成。

  2. 当ExtClassLoader加载一个class时,它首先也不会自己去尝试加载这个类,而是把类加载请求委派给BootStrapClassLoader去完成。

  3. 如果BootStrapClassLoader加载失败(例如在$JAVA_HOME/jre/lib里未查找到该class),会使用ExtClassLoader来尝试加载;

  4. 若ExtClassLoader也加载失败,则会使用AppClassLoader来加载,如果AppClassLoader也加载失败,则会报出异常ClassNotFoundException。

双亲委派优势

  • 系统类防止内存中出现多份同样的字节码

  • 保证Java程序安全稳定运行

  • JVM内存结构:

   

标签:初始化,Java,ClassLoader,该类,机制,Class,加载
From: https://www.cnblogs.com/DonghaiOK/p/16894013.html

相关文章

  • 有趣的 Go HttpClient 超时机制
    hello,大家好呀,我是既写Java又写Go的小楼,在写Go的过程中经常对比这两种语言的特性,踩了不少坑,也发现了不少有意思的地方,今天就来聊聊Go自带的HttpClient的超时机制......
  • vue打包后网页首次打开加载慢
    二、nginx配置server{gzipon;gzip_buffers324K;gzip_comp_level6;gzip_min_length100;gzip_typesapplication/javascripttext/csstext/xml;gzip_disable"M......
  • .NET 7 升级Visual Studio 2022 17.4发生 WorkloadManifest.json冲突,导致项目无法加载
    .NET7的发布,升级VisualStudio2022的17.4版本,然后无法打开所有解决方案。提示信息如下异常:SDK解析程序失败:"尝试解析SDK"Microsoft.NET.Sdk"时,SDK解析程序”Microsoft.Do......
  • leaflet 加载高德地图自定义样式
    最近项目需求,需要使用leaflet封装成一个vue组件,涉及功能主要有高德自定义样式地图封装为leaflet底图图层、自定义坐标系、topjson省市区街道下钻、线面区域热力层、飞线、......
  • JAVA系列之类加载机制详解
    类的加载机制?双亲委派机制?什么是类加载器?自定义类加载器有哪些应用场景?通常,在关于Java的类加载部分会遇到以上疑问,本文将对类加载重要部分做详细介绍,包括重要的......
  • unity 通过场景名称实现动态加载背景BGM音乐
    在场景中创建一个空物体对象,然后将代码挂载到空物体需要注意的是,场景中需要有以下组件一般在主摄像头里 添加到代码挂载的空物体上将场景中类的公开变量s......
  • unplugin-vue-components(按需加载使用的组件)
    作用unplugin-vue-components是由vite-plugin-components重名而来,可以将项目中的组件按需引用,仅注册你使用的组件。//平时我们在页面使用组件<template> <comp/></t......
  • 深度剖析React懒加载原理
    目录代码分割React的懒加载import()原理React.lazy原理Suspense原理参考1.代码分割(1)为什么要进行代码分割?现在前端项目基本都采用打包技术,比如Webpack,JS......
  • 类加载机制
    启动类加载器扩展类加载器应用程序类加载器自定义类加载器定义:当一个类加载器收到了类加载的请求的时候,他不会直接去加载指定的类,而是把这个请求委托给自己的父加载器......
  • UnionID 机制说明
    如果开发者拥有多个移动应用、网站应用、和公众帐号(包括小程序),可通过UnionID来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号(包括......