JVM类加载机制(算是白话)有问题欢迎评论
JVM类加载机制
类加载运行全过程
首先当我们用java命令运行某个类的main函数启动程序时,首先需要通过类加载把主类加载到JVM中(就是这个类分配内存 分配内存的方法在后续会写 往下看)
这里补充一个知识 栈帧(就是当调用方法时 会给这个方法创建一个内存空间也可以叫做内存区域 可以参考idea运行程序时 下面控制台旁边的栈那就是一个一个的栈帧 一个方法对应一块栈帧内存区域)
当执行java指令(也可以叫命令)时主要做了一些事(就是如何把这个类加载到jvm内存中)
首先有一个java.com.tuling.jvm.Math类我们对它使用java这个指令 这里是c++实现的 然后它主要做了Math(表示使用了java这个指令 然后它做的事情看箭头)这是第一步 ---》在Windows系统下java.exe(这个可以说是java指令)调用底层的jvm.dll(相当于java的jar 这是c++的库函数)然后创建java虚拟机(c++实现)这是第二步 ---》然后创建一个引导类加载器实例(c++实现)到这里往下有两个选择 这里先写一个 另一个会在下面写 这是第三步 --c++调用java代码创建JVM启动器实例sun.misc.Launcher,该类由引导类加载器负责加载 然后创建其他类加载器(类加载器都有什么会在下面写)这里的是当第三部执行会做的一些事情--》然后就运行sun.misc.Launcher(读音老车).getLauncher()这个方法 这是第四步 --第四步会获取运行类自己的类加载器ClassLoader是AppClassLoader的实例--》launcher.getClassLoader() 【launcher是创建对象的一个变量名 类型为Launcher(读音老车)这个类主要是用来加载类的java层面】 这是第五步 --调用loadClass加载要运行的类Math 也就是从第五步才开始加载我们自己写的Math类--》classLoader.loadClass("com.tuling.jvm.Math")就是通过这个方法加载我们自己写的类 这是第六步 --加载完成时JVM会执行Math类的main方法入口--》Math.main() 第七步 一个类的加载就算完了 --java程序运行结束--》JVM销毁第八部上面写到还有另外一个选择 这个选择就是从上面的第三步开始 --c++发起调用--》 Main.main() 第四步 --java程序运行结束--> JVM销毁 第五步 以上就是一个类加载时的大体流程每一个为了方便看 每一个换行表示一步!!!!!!!!!!!!
其中loadClass的类加载过程有一下几步
加载》》验证》》准备》》解析》》初始化》》使用》》卸载
其中 加载、验证、准备、解析、初始化 这五部为重要
加载:加载就是在硬盘上找这个字节码文件 然后在使用的时候 比如new、main()方法给这个类加载到内存 然后在jvm内存中创建代表这个类的java.lang.class对象 当做方法区然后通过这个使用这个类中的各种数据验证:验证就是看看这个文件是不是一个字节码文件就是判断这个文件的正确性准备:准备就是给类 分配内存空间 给静态变量赋予默认值解析:就是将 符号引用(符号引用 符号就是public void static a(){} 返回值 方法名 修饰符 都可以叫做符号 符号引用就是 现在a表示这个方法) 替换为 直接引用 (直接引用 就是把a换成它在内存中的哪个 内存地址) 这一步叫做 静态链接 还有一个动态链接 可以理解为程序在运行期间的 符号引用替换为直接引用 就是对那些不是静态的方法 做处理初始化:初始化就是对类中的静态变量进行赋真正的值,执行静态代码块一个类被加载到方法区中后有 运行时常量池、类型信息、字段信息、方法信息、类加载的引用、对应的那个class实例引用等类加载器的引用:这个类是被哪个类加载器加载的对应的哪个class实例引用:当一个类放入方法区后会创建一个Class类型的对象实例放入堆中 让我们java开发人员想对这个类进行详细使用的一个入口一个切入点 比如反射当主类在运行时会逐步加载使用到的类 不是一次性全部加载的!!!!!!!!!!!!比如一个jar包或者war包中可能会有好多类 这些类会在用到的时候逐步加载
这里将要说的 类加载器和双亲委派机制
可以通过Class类中的getClassLoader()方式得到 类的加载器上面说的类加载过程主要是通过类加载器实现 java的加载器为引导类加载器、扩展类加载器、应用程序类加载器、自定义类加载器引导类加载器:负责加载支撑JVM运行的一些类位于JRE的lib目录下的核心类库,比如tr.jar、charsets.jar等扩展类加载器:负责加载支撑JVM运行的一些类位于JRE的ext扩展目录下的jar包应用程序加载器:负责加载ClassPath下类 主要加载我们自己写的一类自定义类加载器:负责加载我们自己设置的路径下的类类加载器初始化过程 在sum.misc.Launcher类中的构造方法中实现 (这里实现了扩展类加载器、应用程序类加载器 都是这个Launcher类中的内部类)sum.msic.Launcher初始化使用单例模式设计,但是构造方法是被public修饰很奇怪构造方法中创建的扩展类加载器代码为 sum.msic.Launcher.getExtClassLoader()应用程序类加载器代码为 sum.msic.Launcher.getAppClassLoader()通过上面说的那八步根据看Launcher源码所得出 JVM默认使用Launcher的getClassLoader()方法返回的类加载器的实例来加载我们的应用程序 默认返回AppClassLoader 由c++调用 根据上面写的一个类的加载第四步得到 双亲委派机制!!!!!!!!!JVM类加载器是有一个结构从自定义加载器开始往上找引导类加载 《--- 扩展类加载器 《--- 应用程序类加载器 《--- 自定义加载器失败后从引导类加载器引导类加载器(爷爷) ---》 扩展类加载器(爸爸) ---》 应用程序类加载器(儿子) ---》 自定义加载器(孙子)以上是双亲委派大体流程 下面详细说怎么个过程根据上面说的一个类的加载 类的加载其实有一个叫双亲委派的机制 双亲委派机制的流程 在加载到某个类时会先委托父加载器 让父加载器寻找这个类,找不到再委托上层父加载器(爷爷)加载这个类 如果所有父加载器在自己的加载类的路径下都找不到这个类,则在自己的类加载路径中查找并载入目标类比如Math类(自己写的一个类上面提到用来当一个例子),最先会找应程序类加载器加载,应用程序类加载器会先委托扩展类加载器加载,扩展类加载器再委托引导类加载器,顶层引导类加载器在自己的类加载路径里找了半天找不到Math类就会 向下退回加载Math类的请求,扩展类加载器收到回复就自己加载,在自己的类加载路径中查找并载入目标类,如果没找到Math类 又会向下退回加载Math类的请求 当应用程序类加载器收到回复就自己加载,在自己的类加载路径中查找并载入目标类(Math这个类)找到了就自己加载找不到就给自定义加载器(如果有的话)也是跟上面的加载器的过程一样 双亲委派机制一句话就是 先给儿子 儿子让父加载 父有就加载 没有就向下退回让它自己加载 向上的过程没有去加载类路径中查找 向下的时候查找的至于为什么应用程序类加载器为儿子 扩展类加载器为父 引导类加载器为爷爷(这个是c++实现在java层面看不到 要看java源码才能看到) 儿子跟父 可以在Launcher这个类的构造方法中查看 打开idea搜索这个类即可 双亲委派机制的源码在ClassLoader类的loadClass()方法中可以看到 就在那个 if (parent != null) {}在这个if中的哪行代码就是// First, check if the class has already been loaded双亲委派首先会检查这个类是否加载 上面的英文是源码中的 到loadClass()方法中就能看到 自己写一个类在这个方法中弄一个条件断点 name.eaquals("包名加类名")为什么会有双亲委派机制!!!!!!!!!!!!!!!!!!!!!!!!!!1、沙箱安全机制:自己写的java.lang.String.class类不会被加载,防止核心API被随意篡改2、避免类的重复加载:当父亲已经加载了该类时,就没有必要子ClassLoader再加载一次,保证类被加载的唯一性全盘负责委托机制全盘负责是指当一个ClassLoader装在一个类时,除非显示的使用另外一个类加载(ClassLoader) 否侧该类中用到的别的类也用这个类加载器(ClassLoader)加载自定义类加载器实例自定义类加载至于要集成java.lang.ClassLoader这个类,这个类由两个核心方法,一个是loadClass(String,boolean),实现了双亲委派机制, 还有一个方法是findClass,默认实现是空方法findClass()这个方法根据看源码上面注释 作用就是加载类的字节码文件 就是写一个io流把这个字节码加载进来就行 然后defineClass(String name, byte[] b, int off, int len,ProtectionDomain protectionDomain)调用这个方法 参数可以参考ClassLoader中调用这个方法的地方 把b参数换成我们刚刚用io流加载的哪个字节码文件即可defineClass()这个方法根据源码注释写到是用来解析这个字节码的打破双亲委派机制!!!!!!!!!!!!!!!!!打破双亲委派机制根据上面步骤加上重写loadClass方法即可 传的参数也可以参考ClassLoader()源码中调用这个方法的地方
从C++到java类的过程
一个类的加载
JVM类加载机制(算是白话)有问题欢迎评论相关推荐
- 深入理解JVM虚拟机6:深入理解JVM类加载机制
深入理解JVM类加载机制 简述:虚拟机把描述类的数据从class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 下面我们具体 ...
- JVM基础系列第7讲:JVM 类加载机制
当 Java 虚拟机将 Java 源码编译为字节码之后,虚拟机便可以将字节码读取进内存,从而进行解析.运行等整个过程,这个过程我们叫:Java 虚拟机的类加载机制.JVM 虚拟机执行 class 字节 ...
- jvm类加载机制_面试:对于JVM类加载机制深度解析
目录: 前文回顾 JVM在什么情况下会加载一个类? 从实用角度出发,来看看验证.准备和初始化的过程 核心阶段:初始化 类加载器和双亲委派机制 1.前文回顾 咱们今天先来回顾一下昨天讲到的JVM整体的一 ...
- 【Java虚拟机规范】JVM类加载机制
[Java虚拟机规范]JVM类加载机制 理论知识 一个类型从被加载到虚拟机内存中开始,到卸载出内存为止,它的整个生命周期将会经历加载(Loading).验证(Verification).准备(Prep ...
- jvm类加载机制_JVM 类加载机制
学习导图 一.为什么要学习类加载机制? 今天想跟大家唠嗑唠嗑 Java 的类加载机制,这是 Java 的一个很重要的创新点,曾经也是 Java 流行的重要原因之一. Oracle 当初引入这个机制是为 ...
- JVM类加载机制(ClassLoader)源码解析
http://blog.csdn.net/chenyi8888/article/details/7066569 其实JVM类加载机制,简单地说就是类管理,也就是我们生成的class文件. 三个步骤:装 ...
- JVM(2)——JVM类加载机制
一.JVM类加载机制简介 虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是虚拟机的类加载机制. 在Java语言里面 ...
- jvm类加载机制和类加载器_在JVM之下–类加载器
jvm类加载机制和类加载器 在许多开发人员中,类加载器是Java语言的底层,并且经常被忽略. 在ZeroTurnaround上 ,我们的开发人员必须生活,呼吸,饮食,喝酒,并且几乎与类加载器保持亲密关 ...
- JVM类加载机制详解
本文来详细说下JVM类加载机制 文章目录 概述 类加载器是什么 类加载的过程 加载 连接 初始化 类的主动引用和被动引用 主动引用 被动引用 三种类加载器 双亲委托机制 核心思想 源码分析 类的动态加 ...
最新文章
- CF 1098 C. Construct a tree
- MYSQL 生成UUID() 即 ORACLE 中的guid()函数
- Spring3MVC+Mybatis3.1框架下的事务
- SQL SERVER 常用日期计算
- maven 上传jar 包含源码
- html=r.text,在R中使用text()
- python的基本语术_Python中的基本语句详细资料说明
- IOS开发之----常用函数和常数--秀清
- 前端学习(2012)vue之电商管理系统电商系统之手动为upload组件添加请求头
- 每日一题(24)—— const
- 如何在 Linux 上重命名一组文件
- (一)PyQt5基础学习
- 2014年java软件project师面试题收集
- TextToSpeech问题总结
- ps 打开失败 提示:暂存盘已满
- 还在使用手写笔记?又或者使用TXT、Word做笔记?NoNoNo,你需要一款合适的电子笔记!
- JSON for Modern C++
- matlab 分类学习工具箱 Classification Learner的使用及导出其生成的图,混淆矩阵confusion matrix的画法
- Truth or dare - 真心话大冒险片尾曲
- 金仓数据库 KingbaseGIS 使用手册(9.4. 拓扑结构构造函数、9.5. 拓扑结构编辑函数)
热门文章
- python 小游戏
- 08年约两千万农民工因金融危机失去工作返乡
- oracle rman ora19602,学习笔记:OracleRMAN备份入门 将RMAN备份数据放到nfs远程文件系统中...
- 闪电的驯服者:电学的历史
- python处理音频的软件_『开发技巧』Python音频操作工具PyAudio上手教程
- 上海居住证续办流程须知 -- 7月新政后居住证制度改革
- case_02 股票波动率计算
- Python Dash(二)
- 计算机中文核心期刊和核心期刊影响因子
- netty——Channl的常用方法、ChannelFuture、CloseFuture