彻底搞懂JVM类加载器:基本概念
点击蓝色“程序猿DD”关注我
回复“资源”获取独家整理的学习资料!
作者 | 阿杜的世界
简单讲下JVM中的类加载过程
JVM中的类加载和卸载的时机?
如何理解JVM中不同类加载器的概念和作用?
简单讲下JVM中的双亲委派模型?
什么情况下会破坏双亲委派模型?为什么?可否举个例子?
Tomcat中的类加载机制有了解吗?为什么这么设计?
实际开发中有遇到哪些类加载器相关的问题?你又是如何解决的?
JVM之上的弱类型语言例如Groovy是如何实现?简单讲下动态类加载机制?
基本概念篇
类的加载和卸载
JVM是虚拟机的一种,它的指令集语言是字节码,字节码构成的文件是class文件。平常我们写的Java文件,需要编译为class文件才能交给JVM运行。可以这么说:C语言代码——>二进制文件——>计算机硬件,就相当于Java代码——>字节码文件——>JVM。JVM将指定的class文件读取到内存里,并运行该class文件里的Java程序的过程,就称之为类的加载;反之,将某个class文件的运行时数据从JVM中移除的过程,就称之为类的卸载。
class文件的运行时数据就是C++对象,也称为kclass对象,这些运行时数据在JDK7之前是放在永久代(PermGen),JDK8之后则放在元空间(Metaspace)。
类的生命周期
Java类从被虚拟机加载开始,到卸载出内存为止,它的整个生命周期包括:加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)7个阶段;其中验证、准备和解析又统称为连接(Linking)阶段。
类的加载的时机
虚拟机规范并未严格规定类加载的时机,跟具体的JVM虚拟机有关。类加载的最佳时机是解析Java字节码类文件中常量池符号的时候,Class.forName()、ClassLoader.loadClass()、反射API和JNI_FindClass都可以触发类加载,Hot JVM自身启动的时候也会触发类加载。
通过JVM参数中加 -verbose:class
,可以在应用启动的时候打印类加载的过程,如下图所示:
初始化这个阶段,JVM虚拟机给出了5种必须对类进行“初始化”的情况
使用new关键字实例化对象的时候、读取或设置一个类的静态字段的时候、调用一个类的静态方法的时候;
使用java.lang.reflect包的方法对类进行反射调用的时候,如果类没有进行过初始化,则要先触发其初始化;
当初始化一个类的时候,如果发现其父类还没有被初始化,则要先初始化其父类;
当虚拟机启动时,用户需要指定一个执行的主类(包含main方法的那个类),则虚拟机会优先初始化这个主类;
在JDK1.7以后,动态语言支持的时候,如果一个java.lang.invoke.MethodHandle实例最后的结果是要执行第1种情况的操作,则也要进行初始化。
类的卸载时机
类的卸载跟采用的垃圾收集算法有关,在CMS中有两种方法卸载不必要的类,一种是等到元空间(Metaspace)满了的时候触发FGC,另一种是使用跟CMS并发收集算法类似的方式,不过对于元空间的阈值和触发CMS并发收集的阈值是独立的。更具体的可以参考之前的文章:CMS学习笔记。在这里,我们只需要记住,JVM中一个类的卸载要满足下面这3个条件:
该类所有的实例对象都已被回收;
该类的类加载器对象已经被回收;
该类对应的java.lang.Class对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。
类加载器的作用
类的加载是需要类加载器完成的,但是类加载器在JVM中的作用可不止这些。在JVM中,一个类的唯一性是需要这个类本身和类加载一起才能确定的,每个类加载器都有一个独立的命名空间。
不同的类加载器,即使是同一个类字节码文件,最后再JVM里的类对象也不是同一个,下面的代码展示了这个结论:
上述代码的运行结果是:
可以看出,代码中使用自定义类加载器(myLoader)加载的jvm.ClassLoaderTest类和通过应用程序类加载器加载的类不是同一个类。综上,类加载器在JVM中的作用有:
将类的字节码文件从JVM外部加载到内存中
确定一个类的唯一性
提供隔离特性,为中间件开发者提供便利,例如Tomcat
总结
今天的文章,应该可以回答文章开始提出的前两个问题,下篇再会。
参考资料
https://jrebel.com/rebellabs/do-you-really-get-java-classloaders/
https://stackoverflow.com/questions/2424604/what-is-a-java-classloader
https://docs.oracle.com/javase/9/docs/api/java/lang/ClassLoader.html
https://www.ibm.com/developerworks/cn/java/j-lo-classloader/index.html
https://blogs.oracle.com/sundararajan/understanding-java-class-loading
《深入理解Java虚拟机》
《揭秘Java虚拟机》
《Java性能权威指南》
本文通过OpenWrite的免费Markdown转换工具发布
-END-
留言交流不过瘾
关注我,回复“加群”加入各种主题讨论群
朕已阅
彻底搞懂JVM类加载器:基本概念相关推荐
- jvm类加载器以及双亲委派
首先来了解几个概念: 类加载: 概念:虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验--转换解析--初始化,最终形成能被java虚拟机直接使用的java类型,就是jvm的类加载机制. ...
- Java高并发编程详解系列-JVM类加载器
之前的博客中提到了类加载的过程,提到了双亲委托机制,提到了关于类加载器的概念,这篇博客就来给大家分享一下什么是JVM的类加载器.通过实战的方式来了解一下类加载器器到底是什么. JVM类加载器分类 ...
- 学习java多线程,这必须搞懂的这几个概念
转载自 学习java多线程,这必须搞懂的这几个概念,很重要. 同步和异步 同步,Synchronous,即调用方法开始,一旦调用就必须等待方法执行完返回才能继续下面的操作. 举个例子,你去银行ATM取 ...
- 不要做一个「永远没彻底搞懂」诸如递归等概念的程序员
Don't be the person who "never quite understood" something like recursion. https://teachyo ...
- java中判断undefined_Java虚拟机系列一:一文搞懂 JVM 架构和运行时数据区
前言 之前写博客一直比较随性,主题也很随意,就是想到什么写什么,对什么感兴趣就写什么.虽然写起来无拘无束,自在随意,但也带来了一些问题,每次写完一篇后就要去纠结下一篇到底写什么,看来选择太多也不是好事 ...
- 一篇文章读懂Java类加载器
Java类加载器算是一个老生常谈的问题,大多Java工程师也都对其中的知识点倒背如流,最近在看源码的时候发现有一些细节的地方理解还是比较模糊,正好写一篇文章梳理一下. 关于Java类加载器的知识,网上 ...
- 22-09-02 西安 JVM 类加载器、栈、堆体系、堆参数调优、GC垃圾判定、垃圾回收算法、对象的finalize机制
这篇文章不少地方都截图了宋红康老师的课件,实在他jvm这块讲的真好.连接地址如下: 尚硅谷宋红康JVM全套教程(详解java虚拟机)_哔哩哔哩_bilibili JVM入门 1.JVM结构图 JVM是 ...
- JVM 类加载器与双亲委派模型
1. 类加载器 我们知道,虚拟机在加载类的过程中需要使用类加载器进行加载,而在 Java 中,类加载器有很多,那么当 JVM 想要加载一个 .class 文件的时候,到底应该由哪个类加载器加载呢?这时 ...
- JVM 类加载器详解
类加载器作用: 类加载器子系统作用: 1. 类加载器子系统负责从文件系统或者网络中加载Class文件,class文件在文件开头有特定的文件标识. 2. ClassLoader只负责class文件的加载 ...
最新文章
- 获取oracle数据库war报告,Oracle 数据库开发及SQL基础实战
- Special Judge Ⅲ(这道题考的就是出栈序列判定_关键代码不差什么)
- 浅谈5G机房配套那些事
- QQ浏览器如何查看网站保存的密码
- Android应用内存泄漏的定位、分析与解决策略
- 分布式消息系列:详解RocketMQ的简介与演进、架构设计、关键特性与应用场景
- 2021年下半年软考系统集成项目管理工程师真题及答案解析
- AI圣经 PRML《模式识别与机器学习》-读书笔记汇总贴
- F检验 matlab
- 加载mysql驱动失败_java mysql 驱动加载失败
- Glide异步加载图片,设置默认图片和错误图片
- 事业单位计算机类岗位考试试题,国家机关(事业单位)计算机岗位考试试题
- input的onkeyup事件
- 【进阶Python】第一讲:开篇
- 「传统的互联网模式」呈现的是粗放式的,野蛮生长的状态
- 荣耀50和小米civi参数对比
- 代码自测(输入任意两个整数,输出他们的最大公约数和最小公倍数 )-2021-7-16
- Jenkins自动化部署详细教程
- python中fig_Matplotlib画图中fig,ax,plt的区别和联系
- 联想开天s620z改win7和Linux,联想台式机10代cpu改win7系统步骤
热门文章
- shodan 渗透测试 漏洞挖掘 一些用法
- linux 挂载错误 mount: unknown filesystem type LVM2_member 解决方法
- linux centos 挂载ntfs文件系统
- linux yum错误 14: PYCURL ERROR 6 - Couldn't resolve host 'mirrorlist.centos.org'
- Android开发--Http操作介绍(二)
- Linux 有趣命令
- Linux中printk()实例
- Java的深拷贝和浅拷贝
- TCP/IP详解--第八章
- php能力模型,ThinkPHP5--基础篇(模型)