JVM学习笔记之类装载器-ClassLoader
JVM学习笔记之类装载器-ClassLoader
本文字数:2300,阅读耗时7分钟
JVM体系结构概览
类装载器ClassLoader:
负责加载class文件,class文件在文件开头有特定的文件标识,将class文件字节码内容加载到内存中,并将这些内容转换成方法区中的运行时数据结构并且ClassLoader只负责class文件的加载,至于class文件是否可以允许,则由Execution Engine决定。
本文是由凯哥Java(WXID:kaigejava)分享《JVM系列教程》
我们来看看Java类编译成class文件后,文件开头特定的文件标识是什么样的?如下图:
类加载器
类加载器的分类:
JVM自带的三个类加载器
启动类加载器:Bootstrap 使用C++语言写的
扩展类加载器:Extension 使用Java语言写的
应用程序类加载器:AppclassLoader。Java也叫系统类加载器,加载当前引用的classPath所有类。
用户自定义加载器:
需要继承Java.lang.ClassLoader的子类。
几种类加载器关系如下图:
代码演示:
一:启动类加载器--查看Object的类加载器
执行:
Object obj = new Object();
System.out.println("obj classLoader:"+obj.getClass().getClassLoader());
执行后,我们发现obj的类加载器是null .如下图:
分析原因:Object是所有类的父类。是顶级对象。因为是顶级的,所有object的类加载器使用的是bootstrap类加载器。也即调用的是最底层的,所以就是null.
二:查看自定义类的类加载器
自定义一个类:MyObject输出该类的classloader:
sun.misc.Launcher$AppClassLoader.如下图:
我们可以看到,自定义类的类加载器来自于AppClassLoader.也即是应用服类加载器。
思考:
为什么我们安装jdk之后,就可以直接使用string类、list类等这些类呢?这些类是什么时候被加载进去的呢?
代开jdk安装目录,找到jre,然后再lib文件夹下找到rt.jar.这个jar就是Java运行时需要的。解压后,我们找到java.lang.string:
现在知道为什么,安装jdk之后,我们就可以直接使用很多类了吧。因为这些类所在的jar再启动的时候,就被bootstap启动类加载器加载了,所以我们就可以直接使用了!!
怎么证明rt.jar被加载的呢?
我们从自定义的类加载器:sun.misc.Launcher$AppClassLoader。根据包名插在Launcher类所在的位置:
我们是在rt.jar中的sun\misc包下找到的。
说明:launcher是一个Java虚拟机的入口应用
三:扩展类加载器
扩展类加载器时什么?怎么用?
根据名字,我们就可以知道,该加载器是为了扩展Java功能的,不被淘汰的。在Java的API中,我们会看到很多,javax.xxx的。这些javax包下的类就是扩展类加载器管理的。
对应jre中的ext文件夹下:
四:自定义类加载器的层级关系:
下面代码执行后的结果是什么?
private static void showMyObjectClassLoaderLeve() {
MyObject myObject = new MyObject();
System.out.println("MyObject 的爷爷:"+myObject.getClass().getClassLoader().getParent().getParent());
System.out.println("MyObject 的爸爸:"+myObject.getClass().getClassLoader().getParent());
System.out.println("MyObject 自己的:"+myObject.getClass().getClassLoader());
}
从运行结果中我们可以看到:
自定义类的类加载器是:AppClassLoader
其父加载器:ExtclassLoader
其父加载器的父加载器:null
从这个层级关系中,我们就可以知道,原来我们自己写的类是在扩展类加载器下。
思考:
如果是object.getclass().getClassLoader().getParent()会输出什么?
答案是:会抛出空指针异常。为什么呢?因为Object是jvm自带的。没有父加载器了。
五:用户自定义的类加载器
需要继承Java.lang.ClassLoader这个类,然后在自定义处理。
如何更好的理解JVM的几种类加载器呢?
我们生活在地球上,其中空气、水、阳光这些是我们必须且赖以生存的基本条件,这三个就相当于是JVM的启动类加载器(BootStap加载器);
为了能安全的生存下去,抵挡自然界或是外界威胁,我们组成了团体,最后组成国家,有了国家的军队保护着就安全了。这就相当于是扩展类加载器(Externsion Class Loader)
要想成为中国人,拥有中国国籍的话,需要至少父母一方是中国人(其他特殊情况不考虑),这个就相当于是应用程序类加载器(AppClassLoader)了;
如果想要生活的更好,自己就要努力,就要有个好工作,有一套属于自己的房子。这个就相当于是用户自定义的类加载器了。
简图如下:
接下来学习:Java的双亲委派机制及沙箱安全机制是什么?如何理解jvm的双亲委派机制?用代码如何验证?欢迎大家和凯哥Java(WXID:kaigejava)一起继续学习

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Intel 20G 内部资料泄露,含源码、文档与培训视频等内容
网传 Intel 有 20GLake 系列处理器相关的机密文档与源码遭到黑客泄露,这些内容大多数以往从未在任何地方发布过,并且被归类为“机密级别”。泄露者还扬言,接下来还会分享更多劲爆资料。 根据曝光者梳理,目前已公开的部分主要为 Lake 系列处理器相关内容,还包括Kaby Lake BIOS 源码、Intel 为 Space X 开发的相机驱动、Rocket Lake S 模拟材料、Elkhart Lake 参考代码等,具体如下: 此外有意思的是,泄露者还表示,如果遇到有文件被加密,可以尝试 Intel123、intel123 与 I accept 这样简单的密码解开。 同时在源码中搜索“backdoor(后门)”这样的字眼也会有有趣的发现。 目前泄露的资料上传在 Mega:https://mega.nz/folder/CV91XLBZ#CPSDW-8EWetV7hGhgGd8GQ,同时曝光者表示 Telegram 上也已经传开。
-
下一篇
教你几招,快速创建 MySQL 五百万级数据
我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面。 如果你打算好好学习一下 MySQL,性能优化肯定是绕不过去一个问题。当你撸起袖子准备开始的时候,突然发现一个问题摆在眼前,本地数据库中没那么大的数据量啊,几条数据优化个毛线啊。生产库里数据多,但谁敢直接在生产环境动手啊,想被提前优化吗? 要知道,程序员从不轻言放弃,没有数据我们就自己创造数据嘛,new 对象这种事情可是我们的拿手好戏,对象都能 new 出来,更别说几百万条数据了。 使用官方数据 官方显然知道我们需要一些测试数据做个练习什么的,所以准备了一份测试数据给我们。可以到 https://github.com/datacharmer/test_db 上去下载,这个数据库包含约30万条员工记录和280万个薪水条目,文件大小为 167 M。 下载完成之后,直接使用 MySQL 客户端运行 sql 文件即可。 或者直接使用命令,然后输入密码导入。 mysql -u root -p ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Dcoker安装(在线仓库),最新的服务器搭配容器使用
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8编译安装MySQL8.0.19
- SpringBoot2初体验,简单认识spring boot2并且搭建基础工程
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- SpringBoot2全家桶,快速入门学习开发网站教程