深入理解Java虚拟机5-chap7-斗者2星
一、类加载机制
1.类加载机制:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验、转换解析和初始化,最终形成可以被虚拟机直接使用的Class文件加载到内存,这就是类加载机制。
2.类型的加载、连接和初始化过程发生在运行期。
3.Java动态扩展:依赖运行期动态加载与动态连接。
4.本地程序运行时Class文件可以来源于网络或者其他地方,称为程序的一部分,如OSGi技术。.
二、类加载时机
1.类的生命周期
- 加载、验证、准备、初始化和卸载:这5个阶段按照如此顺序开始
- 解析可能发生在使用阶段,来支持运行时绑定
2.初始化发生的5个条件(加载、验证、准备当然要提前完成)
- 遇到 new、 getstatic、 putstatic 或 invokestatic 这 4 条字节码指令时,如果类没有进行过初始化,则需要先触发其初始化。
- 使用 java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化。
- 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化。
- 当虚拟机启动时,用户需要指定一个要执行的主类(包含 main() 方法的那个类),虚拟机会先初始化这个主类。
- 当使用 JDK1.7 的动态语言支持时,如果一个 java.lang.invoke.MethodHandle 实例最后的解析结果 REF_getStatic、 REF_putStatic、 REF_invokeStatic 的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。
3.上述5个条件为对类的主动引用,其他引用类的方式不会触发初始化,称为被动引用
- 通过子类引用父类的静态字段
- 通过数组定义引用类,如Shape[] s = new Shape[10];
- 引用类的static final域,由于在编译阶段会存入调用类(使用者)的常量池,本质并没有直接引用到定义常量的类
三、类加载过程
1.加载
1)加载阶段需要完成的三件事
- 通过一个类的全限定名来获取定义此类的二进制字节流。
- 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构(包括类型信息吧...)。
- 在内存中生成一个代表这个类的 java. lang. Class 对象,作为方法区这个类的各种数据的访问入口。
2)数组:不通过类加载器加载,由Java虚拟机直接创建的
2.验证
1)目的:自我保护
2)验证阶段工作量占类加载相当大一部分
3)具体检验动作
- 文件格式验证:魔数、版本号、常量池tag、编码等,本种验证基于二进制字节流,通过后,字节流进入内存的方法区储存,后面验证基于内存
- 元数据验证:语义分析,保证描述信息符合语言规范,如是否有父类、类的父类是否继承了不允许继承的类、如果为抽象类是否实现了所有抽象方法等
- 字节码验证:确定程序语义合法,如确定数据和指令可以配合工作、保证跳转指令不会跳转到方法体外的字节码指令上、保证类型转换有效(不出现将一个类型转换为另外一个无关类型)等,由于数据流验证的高复杂性,可通过StackMapTable优化
- 符号引用验证:符号引用转换为直接引用时(解析阶段),如符号引用通过字符串全限定名能否找到对应的类、是否存在所描述的方法和类、符号引用中的类、方法、字段的访问性是否可被当前类访问,其实并非必要!
3.准备
- 目的:正式为类变量分配内存并设置类变量的初始值,对于非final变量为0,对于final变量,需要执行其初始化流程
4.解析
- 将常量池的符号引用替换为直接引用
- 符号引用:与内存无关,直接引用:与内存有关
- 除了invokedynamic指令,JVM可能对第一次解析的结果进行缓存
- 类或接口解析、字段解析、类方法解析、接口方法解析
5.初始化
- 初始化阶段是执行<clinit>()的过程
- <clinit>():编译器自动收集类中的所有类变量的赋值动作和静态语句块中的语句合并生成
- 虚拟机保证子类的<clinit>()方法执行之前,父类的<clinit>()方法已经执行完毕
- 保证执行<clinit>()的线程安全性
四、类加载器
1.类加载器
- 类加载过程:JVM之外实现根据一个类的全限定名来获取描述的二进制字节流
- 类层次划分、OSGi、热部署、代码加密均要依赖这个机制
- 每一个类加载器,有其独立的类命名空间,同一个类由不同类加载器加载,则加载的类不相等,包括Class对象的equals()、iAssignableFrom()、isInstance()、instanceof
2.双亲委派
1)三种类加载器:父子关系通过组合实现非继承
- 启动类加载器(Bootstrap ClassLoader):这个类将器负责将存放在
JAVA_HOME\lib
目录中的,或者被-Xbootclasspath 参数所指定的路径中的,并且是虚拟机识别的(仅按照文件名识别,如 rt.jar, 名字不符合的类库即使放在 lib 目录中也不会被加载)类库加载到虚拟机内存中。用户在编写自定义类加载器时,如果需要把加载请求委派给引导类加载器,那直接使用 null 代替即可。 - 扩展类加载器(Extension ClassLoader):它负责加载
JAVA_ HOME\lib\ext
目录中的,或者被 java.ext.dirs 系统变量所指定的路径中的所有类库。 - 应用程序类加载器(Application ClassLoader):由于这个类加载器是 ClassLoader 中的 getSystemClassLoader() 方法的返回值,所以一般也称它为系统类加载器。它负责加载用户类路径( ClassPath) 上所指定的类库。如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器。
2)工作过程
3.破坏双亲委派(OSGi)
参考:
https://gavinzhang1.gitbooks.io/java-jvm-us/content/xu_ni_ji_lei_jia_zai_ji_zhi.html
深入理解Java虚拟机5-chap7-斗者2星的更多相关文章
- 《深入理解Java虚拟机》虚拟机性能监控与故障处理工具
上节学习回顾 从课本章节划分,<垃圾收集器>和<内存分配策略>这两篇随笔同属一章节,主要是从理论+实验的手段来讲解JVM的内存处理机制.好让我们对JVM运行机制有一个良好的概念 ...
- 《深入理解 java虚拟机》学习笔记
java内存区域详解 以下内容参考自<深入理解 java虚拟机 JVM高级特性与最佳实践>,其中图片大多取自网络与本书,以供学习和参考.
- (1) 深入理解Java虚拟机到底是什么?
好文转载:http://blog.csdn.net/zhangjg_blog/article/details/20380971 什么是Java虚拟机 作为一个Java程序员,我们每天都在写Java ...
- 深入理解java虚拟机(7)---线程安全 & 锁优化
关于线程安全的话题,足可以使用一本书来讲解这些东西.<Java Concurrency in Practice> 就是讲解这些的,在这里 主要还是分析JVM中关于线程安全这块的内容. 1. ...
- 深入理解java虚拟机(6)---内存模型与线程 & Volatile
其实关于线程的使用,之前已经写过博客讲解过这部分的内容: http://www.cnblogs.com/deman/category/621531.html JVM里面关于多线程的部分,主要是多线程是 ...
- 深入理解java虚拟机(5)---字节码执行引擎
字节码是什么东西? 以下是百度的解释: 字节码(Byte-code)是一种包含执行程序.由一序列 op 代码/数据对组成的二进制文件.字节码是一种中间码,它比机器码更抽象. 它经常被看作是包含一个执行 ...
- 深入理解java虚拟机(4)---类加载机制
类加载的过程包括: 加载class到内存,数据校验,转换和解析,初始化,使用using和卸载unloading过程. 除了解析阶段,其他过程的顺序是固定的.解析可以放在初始化之后,目的就是为了支持动态 ...
- 深入理解java虚拟机(1)------内存区域与内存溢出
在C++领域,关于C++的内存存储,结构等等,有一本书:深度探索C++对象模型,讲解的非常透彻. 而Java确把这一工作交给了虚拟机来处理. 我们首先来看看关于内存的问题. 1.问题: 1)java ...
- 什么是HotSpot VM & 深入理解Java虚拟机
参考 http://book.2cto.com/201306/25434.html 另外,这篇文章也是从一个系列中得出的: <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> ...
- 【Todo】深入理解Java虚拟机 读书笔记
有一个在线系列地址 <深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)> http://book.2cto.com/201306/25426.html 已经下载了这本书(60多M ...
随机推荐
- 快速开发项目,用到的工具:UI 设置利器 sketch
需求设计: axaure8.0 tool: teambition/石墨.幕布. 接口管理tool(后端开发接口,pc,m,app使用) https://www.eolinker.com/#/ ui 设 ...
- win10 Faster-RCNN训练自己数据集遇到的问题集锦 (转)
题注: 在win10下训练实在是有太多坑了,在此感谢网上的前辈和大神,虽然有的还会把你引向另一个坑~~. 最近,用faster rcnn跑一些自己的数据,数据集为某遥感图像数据集——RSOD,标注格式 ...
- JS保留两位小数的几种方法
四舍五入 以下处理结果会四舍五入: var num =2.446242342; num = num.toFixed(2); // 输出结果为 2.45 不四舍五入 以下处理结果不会四舍五入: 第一种, ...
- 微信小程序——动态设置swiper的高度
根据小程序的设定,swiper组件默认高度为150px,无法根据内容来撑高.如果里面的内容固定还好说,直接设置一个高度就可以了.要是里面内容是动态变化的,这个特性使得我们使用这个组件的时候感到诸多不便 ...
- 从头配置,开发 cocos2dx 3.14.1
要使用cocos2dx写一个麻将测试工具. 配置流程如下: 1. 下载安装最新版本的VS(VS2017): https://www.visualstudio.com/zh-hans/downloads ...
- puppet(5)-master/agent模式
master/agent模式的工作流程 agent每隔固定时长会向master端发送nodename(自己的节点名,节点名至关重要)和 facts ,并且向服务器端请求自己的catalog. mast ...
- error: cannot lock ref 'refs/remotes/origin/master': unable to resolve reference 'refs/remotes/origin/master': reference broken...
之前在自己的项目中添加了一个分支,然后做了一些操作,比如同步本地的分支情况到远程仓库中,然后在远程仓库中完成分支合并,以及 Pull request 等等操作,后来,在本地仓库中进行 git fetc ...
- jquery实现同时展示多个tab标签+左右箭头实现来回滚动
内容: jquery实现同时展示多张图片+定时向左单张滚动+前后箭头插件 jquery实现同时展示多个tab标签+左右箭头实现来回滚动 小颖最近的项目要实现类似如下效果: 蓝色框圈起来的分别是向上翻. ...
- ubuntu中安装blogPost
1.实验环境 Ubuntu16.04x86 2.安装blogPost步骤 2.1 安装方式比较简单,打开ubuntu软件中心 2.2 搜索DB Browser for SQLite,点击安装即可 上图 ...
- layui---表单验证
使用layui,使用它的表单验证也是比不可少的,下面就来总结下: <!-- 不用form 用div也可以 --> <form class="layui-form" ...