类加载机制-深入理解jvm
一、什么是类的加载:
如上图,java文件通过编译器变成了.class文件,接下来类加载器又将这些.class文件加载到JVM中。其中类装载器的作用其实就是类的加载。
二.原理 (类的加载过程及其最终产品):
JVM将class文件字节码文件加载到内存中, 并将这些静态数据转换成方法区中的运行时数据结构,在堆(并不一定在堆中,HotSpot在方法区中)中生成一个代表这个类的java.lang.Class 对象,作为方法区类数据的访问入口。
三.过程(类的生命周期):
加载:
加载过程主要完成三件事情:
- 通过类的全限定名来获取定义此类的二进制字节流
- 将这个类字节流代表的静态存储结构转为方法区的运行时数据结构
- 在堆中生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口。
这个过程主要就是类加载器完成。
校验:
此阶段主要确保Class文件的字节流中包含的信息符合当前虚拟机的要求,并且不会危害虚拟机的自身安全。
- 文件格式验证:基于字节流验证。
- 元数据验证:基于方法区的存储结构验证。
- 字节码验证:基于方法区的存储结构验证。
- 符号引用验证:基于方法区的存储结构验证。
准备:
为类变量分配内存,并将其初始化为默认值。(此时为默认值,在初始化的时候才会给变量赋值)即在方法区中分配这些变量所使用的内存空间。
例如: public static int value = 123;
此时在准备阶段过后的初始值为0而不是123;将value赋值为123的putstatic指令是程序被编译后,存放于类构造器<client>方法之中。
解析:
把类型中的符号引用转换为直接引用。
- 符号引用与虚拟机实现的布局无关,引用的目标并不一定要已经加载到内存中。各种虚拟机实现的内存布局可以各不相同,但是它们能接受的符号引用必须是一致的,因为符号引用的字面量形式明确定义在Java虚拟机规范的Class文件格式中。
- 直接引用可以是指向目标的指针,相对偏移量或是一个能间接定位到目标的句柄。如果有了直接引用,那引用的目标必定已经在内存中存在
主要有以下四种:
- 类或接口的解析
- 字段解析
- 类方法解析
- 接口方法解析
初始化:
初始化阶段是执行类构造器<client>方法的过程。<client>方法是由编译器自动收集类中的类变量的赋值操作和静态语句块中的语句合并而成的。虚拟机会保证<client>方法执行之前,父类的<client>方法已经执行完毕。如果一个类中没有对静态变量赋值也没有静态语句块,那么编译器可以不为这个类生成<client>()方法。
java中,对于初始化阶段,有且只有以下五种情况才会对要求类立刻“初始化”(加载,验证,准备,自然需要在此之前开始):
- 使用new关键字实例化对象、访问或者设置一个类的静态字段(被final修饰、编译器优化时已经放入常量池的例外)、调用类方法,都会初始化该静态字段或者静态方法所在的类。
- 初始化类的时候,如果其父类没有被初始化过,则要先触发其父类初始化。
- 使用java.lang.reflect包的方法进行反射调用的时候,如果类没有被初始化,则要先初始化。
- 虚拟机启动时,用户会先初始化要执行的主类(含有main)
- jdk 1.7后,如果java.lang.invoke.MethodHandle的实例最后对应的解析结果是 REF_getStatic、REF_putStatic、REF_invokeStatic方法句柄,并且这个方法所在类没有初始化,则先初始化。
四.类加载器:
把类加载阶段的“通过一个类的全限定名来获取描述此类的二进制字节流”这个动作交给虚拟机之外的类加载器来完成。这样的好处在于,我们可以自行实现类加载器来加载其他格式的类,只要是二进制字节流就行,这就大大增强了加载器灵活性。系统自带的类加载器分为三种:
- 启动类加载器。
- 扩展类加载器。
- 应用程序类加载器。

双亲委派机制工作过程:
如果一个类加载器收到了类加载器的请求.它首先不会自己去尝试加载这个类.而是把这个请求委派给父加载器去完成.每个层次的类加载器都是如此.因此所有的加载请求最终都会传送到Bootstrap类加载器(启动类加载器)中.只有父类加载反馈自己无法加载这个请求(它的搜索范围中没有找到所需的类)时.子加载器才会尝试自己去加载。
双亲委派模型的优点:java类随着它的加载器一起具备了一种带有优先级的层次关系,不会导致各种自定义加载器家在核心api,统一规范。
例如类java.lang.Object,它存放在rt.jart之中.无论哪一个类加载器都要加载这个类.最终都是双亲委派模型最顶端的Bootstrap类加载器去加载.因此Object类在程序的各种类加载器环境中都是同一个类.相反.如果没有使用双亲委派模型.由各个类加载器自行去加载的话.如果用户编写了一个称为“java.lang.Object”的类.并存放在程序的ClassPath中.那系统中将会出现多个不同的Object类.java类型体系中最基础的行为也就无法保证.应用程序也将会一片混乱.
4、自定义类加载器:
在这一部分第一小节中,我们提到了java系统为我们提供的三种类加载器,还给出了他们的层次关系图,最下面就是自定义类加载器,那么我们如何自己定义类加载器呢?这主要有两种方式
(1)遵守双亲委派模型:继承ClassLoader,重写findClass()方法。
(2)破坏双亲委派模型:继承ClassLoader,重写loadClass()方法。 通常我们推荐采用第一种方法自定义类加载器,最大程度上的遵守双亲委派模型。
我们看一下实现步骤
(1)创建一个类继承ClassLoader抽象类
(2)重写findClass()方法
(3)在findClass()方法中调用defineClass()。
类加载机制-深入理解jvm的更多相关文章
- Java类加载机制的理解
算上大学,尽管接触Java已经有4年时间并对基本的API算得上熟练应用,但是依旧觉得自己对于Java的特性依然是一知半解.要成为优秀的Java开发人员,需要深入了解Java平台的工作方式,其中类加载机 ...
- 类加载机制(深入理解JAVA虚拟机学习笔记)
1.类加载机制的定义 将class文件加载到内存,然后对class文件中的数据进行校验.解析和初始化,转换成可以被虚拟机直接使用的JAVA类型,这就是虚拟机的类加载机制.(在JAVA中,类的加载.连接 ...
- JVM,Tomcat与OSGi类加载机制比较
首先一个思维导图来看下Tomcat的类加载机制和JVM类加载机制的过程 类加载 在JVM中并不是一次性把所有的文件都加载到,而是一步一步的,按照需要来加载. 比如JVM启动时,会通过不同的类加载器加载 ...
- JVM基础系列第7讲:JVM 类加载机制
当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节 ...
- 图解JVM和Tomcat类加载机制
说到本篇的tomcat类加载机制,不得不说翻译学习tomcat的初衷. 之前实习的时候学习javaMelody的源码,但是它是一个Maven的项目,与我们自己的web项目整合后无法直接断点调试.后来同 ...
- 一夜搞懂 | JVM 类加载机制
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图 一.为什么要学习类加载机制? 今天想跟大家唠嗑唠嗑Java的类加载机制,这是Java的一个很重要的创 ...
- JVM初探(三):类加载机制
一.概述 我们知道java代码会被编译为.class文件,这里class文件中的类信息最终还是需要jvm加载以后才能使用. 事实上,虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验,转 ...
- Java JVM类加载机制
虚拟机的类加载机制是:JVM把描述类的数据从.class文件加载到内存,并对数据进行校验.解析.初始化,最终形成可以被JVM直接使用的Java类型. 加载.连接(验证.准备.解析).初始化.使用.卸载 ...
- jvm虚拟机笔记<三> 类文件结构与类加载机制
java虚拟机具有语言无关系,它只和“class文件“这种特定的二进制文件格式绑定. 不同语言的编译器将对应的程序编译成字节码文件(*.class),送给jvm执行. class文件本质上就是一张表, ...
- Java面试题:JVM中的类加载机制
JVM 的类加载机制是指 JVM 把描述类的数据从 .class 文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的 Java 类型,这就是 JVM 的类加载机制. 类 ...
随机推荐
- 【布局技巧】Flex 布局下居中溢出滚动截断问题
在页面布局中,我们经常会遇到/使用这么一类常见的布局,也就是列表内容水平居中于容器中,像是这样: <ul class="g-contaner"> <li>& ...
- Socket是什么/怎么理解Socket
Socket 先来看一下百度百科对于Socket的介绍:套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开.读写和关闭等操作.套接字允许应用程序将I/O ...
- 33. 干货系列从零用Rust编写正反向代理,关于HTTP客户端代理的源码实现
wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...
- HDU-2159 二维背包
最近xhd正在玩一款叫做FATE的游戏,为了得到极品装备,xhd在不停的杀怪做任务.久而久之xhd开始对杀怪产生的厌恶感,但又不得不通过杀怪来升完这最后一级.现在的问题是,xhd升掉最后一级还需n的经 ...
- DRF限流
https://www.django-rest-framework.org/api-guide/throttling/ 限制.控制客户端可以向 API 发出的请求的速率. 设置限流策略 默认限制策略可 ...
- 从零玩转第三方登录之WeChat公众号登陆-cong-ling-wan-zhuan-di-san-fang-deng-lu-zhi-wechat-gong-zhong-hao-deng-lu
title: 从零玩转第三方登录之WeChat公众号登陆 date: 2022-09-03 16:32:57.876 updated: 2022-09-03 16:32:57.876 url: htt ...
- uniapp的app苹果应用商店上架最简教程
除了测试版本之外,uniapp打包好的ipa文件是无法直接安装在普通用户的手机上面,这是苹果的证书和描述文件的机制的原因. 因此我们需要将打包好的ipa文件上架到苹果应用商店,也就是app store ...
- 中间件是开箱即用的吗?为什么要开发中间件adapter?
本文分享自华为云社区<中间件是开箱即用的吗?为什么要开发中间件adapter?>,作者:张俭. 中间件在很多系统中都存在 在一个系统里面,或多或少地都会有中间件的存在,总会有数据库,其他的 ...
- GaussDB(DWS)字符串处理函数返回错误结果集排查
摘要:在使用字符串处理函数时,有时会出现非预期结果的场景.在排除使用问题后,应该从encoding和数据本身开始排查. 本文分享自华为云社区<GaussDB(DWS)字符串处理函数返回错误结果集 ...
- 什么?语音合成开源代码不会跑,follow me!
摘要:本文描述的深度神经网络模型结构:: Natural TTS synthesis by conditioning Wavenet on MEL spectogram predictions. 本文 ...
