深入JVM内核—原理与优化之六类加载器

6 篇文章 0 订阅
1、class 装载验证流程
加载:
装载类的第一个阶段;
取得类的二进制流;
转为方法区的数据结构;
在java堆中生成对应的java.lang.Class对象;
链接(验证、准备、解析):
验证:
目的:保证Class流的格式是否正确;
文件格式的验证:版本号、文件头等;
元数据是否合理:是否有父类;继承final类?;非抽象类实现了所有的抽象方法?
字节码验证(很复杂):运行检查;栈数据类型和操作码数据参数吻合;跳转指令到合理的位置;
准备:分配内存,并为类设置初始值(方法区中);
public static int v=1;在准备阶段中,v会被设置为0;在初始化的<clinit>中才会被设置为 1;
对于static final类型,在准备阶段就会被赋上正确的值,public static final int v=1;
解析:为 方法区常量池里的常量,将符号引用替换为直接引用;
符号引用,字符串引用对象不一定被加载;
直接饮用:指针或地址偏移量,引用对象一定在内存中;
解析不一定非要在准备之后初始化之前进行, 这个阶段的主要任务是使用阶段才会用到的,如果程序中有动态绑定的需求时这时候是没有办法把符号引用准确转换为直接引用的。
初始化
执行类构造器<clinit>
static变量,赋值语句;
static{}语句;
子类的<clinit>调用前保证父类的<clinit>被调用
<clinit>是线程安全的;
后续的是: 使用卸载

我们在文件里写入了java的源代码,源代码写就后存入磁盘,磁盘上的 源代码 经过javac命令的编译形成了 二进制字节码形成了class文件 ,经过一番步骤后java虚拟机将这些二进制字节码按照一定的方式读入内存中的不同区域形成了 二进制字节码的活化状态 ,虚拟机使用字节码指定的命令执行这些指令,其间使用字节码中存储的数据,最终完成了任务。这个过程就是java虚拟机执行java二进制字节码的过程的简单概括。可以如下图所示:
.java--编译-->.class--类加载-->活化字节码--执行-->
类加载:把二进制字节码转为字节流,把它从磁盘里class文件里的二进制字节码将会成为内存不同区域里的数据,虚拟机将这些数据代表的指令执行完成任务。
以上几个步骤就是类加载的全过程,在这个过程中,class文件中的二进制字节码以二进制字节流的形式, 先按照方法区特定的数据结构重整并建立java.lang.Class对象于堆中,
验证重整后的二进制字节流没有语法、语意和安全性的问题后虚拟机为即将加载的类在方法区中开辟内存空间, 字节流注入开辟的方法区的内存空间并将各字段赋零值,常量池中的符号引用转换为有实际意义的直接引用以访问特定的地址,
特定的字段被初始化为程序规定的初值,整个类成功加载到方法区中。
java虚拟机对于类加载过程的初始化的时机,有明确的四个“有且仅有要求”,这些条件下必须对类进行初始化:
new新对象、读写静态字段、调用静态方法的时候必须初始化类:读写静态字段时只初始化这个静态字段所在的类, 如果是父类的静态字段则只初始化父类而不初始化字类;
另外如果是static final修饰的静态字段,那么在编译的时候就会将其写入常量池,这个时候即使读这个静态字段也不会加载类,因为只需要去常量池中取这个值就好。
这两个策略的目的其实都是尽可能地减少类加载的开销;
反射调用的时候初始化类;
初始化类的时候如果父类未初始化要初始化父类;
执行主类(执行的main函数所在类)要初始化。

2、什么是类装载器ClassLoader?
ClassLoader是一个抽象类;
ClassLoader的实例将读入java字节码将类装载到jvm中;
ClassLoader可以定制,满足不同的字节码流获取方式;
ClassLoader负责类装载过程中的 加载阶段
重要方法:loadClass(); defineClass(); findClass(); findLoadedClass();

3、JDK中ClassLoader默认设计模式
BootStrap ClassLoader (启动):rt.jar包等
Extension Classload(扩展):ext包等
App ClassLoad(应用/ 系统): 应用程序下的大多包:Classpath下的类
Customer ClassLoader(自定义)
每个ClassLoad都有一个Parent作为父亲,bootStrp是例外;
查找类方向:自底向上检查类是否已加载:从App --> Bootstrap(父加载器)
加载类方向:自上向底加载:Bootstap --> App;
手工指定bootstap路径:-Xbootclasspath/a:D:/tmp/clz
可以强行加载class,通过反射,强行设置class的Accessble为true,初始化对象
*双亲委派模式问题:顶层ClassLoad-APP无法加载底层ClassLoader-Bootstrap的类;
解决办法:Thread.setContextclassLoader():上下文加载器,是一个角色,用以解决顶层ClassLoader无法访问底层ClassLoader的类的问题;基本思想,在顶层ClassLoader中传入底层ClassLoader的实例;

4、打破常规模式
双亲模式是默认的模式,但不是必须这么做;
tomcat的WebappClassLoader就会先加载自己的class,找不到再委托parent;
OSGI的classloader形成网状结构,根据需要自由加载class
5、热替换



课程简介: 目前,Java是最为流行的编程语言之一,它的基础平台就是JVM。除了Java,如JRuby、Scala、Clojure等语言也运行在JVM平台。熟悉和掌握JVM平台有着重要的实用价值和意义。 在本课程中个,将详细介绍JVM的基本原理、组成以及工作方式,并配合实际案例,介绍相关的调优技巧。 课程大纲: 第一课 初识JVM JVM分类 Java语言规范 JVM规范 介绍JVM的基本知识和发展历史,并介绍了Java语言规范和JVM规范。 第二课 JVM运行机制简介 堆、、方法区等 JVM启动流程 内存模型和volatile实例 解释和编译运行的概念 介绍JVM的内部结构、启动流程以及内存模型。并介绍JVM字节码的执行方式。 第三课 常用JVM参数 堆的分配参数 分配及实例讲解 server与client模式 调试跟踪参数 介绍常用的JVM参数,包括内存分配、堆分配、虚拟机运行模式以及调试跟踪参数。 第四课 GC的算法和种类 引用计数 标记清除 复制算法 标记压缩 可触及性 本章是理论性较强的一章,主要介绍GC的基本算法和思想,本章作为下一章节的前序课程。 第五课 GC控制参数 Serial ParNew等GC参数 GC的参数搭配实例分析 介绍GC的设置参数,并分析相关的案列。 第六课 类装载 class装载流程 ClassLoader模式 ClassLoader的使用实例分析 热替换例子 详细介绍ClassLoader的原理和应用。分析2个案例,说明ClassLoader的使用。 第七课 性能监控工具 线程死锁分析 OOM分析 介绍常用的JVM诊断和分析工具,并以死锁和OOM为例,展示这些工具的使用。 第八课 分析Java堆 MAT的使用案例 Jvisualvm介绍使用 介绍了Java堆的分析方法,以一个实例为基础,展示对堆的分析过程。 第九课 锁 baise锁 轻量级锁 自旋锁 介绍JVM中对多线程锁的实现。 第十课 class文件结构 ASM库介绍 介绍JVM规范中的最重要的内容——Class文件结构,同时介绍ASM库的使用以及对class文件的修改。 第十一课 字节码执行 案例以及javap JIT及相关参数 介绍JVM的字节码以及反汇编方法,同时介绍JIT相关的参数和应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值