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业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
操作系统和并发的爱恨纠葛
我一直没有急于写并发的原因是我参不透操作系统,如今,我已经把操作系统刷了一遍,这次试着写一些并发,看看能不能写清楚,卑微小编在线求鼓励...... 我打算采取操作系统和并发同时结合讲起来的方式。 并发历史 在计算机最早期的时候,没有操作系统,执行程序只需要一个过程,那就是从头到尾依次执行。任何资源都会为这个程序服务,这必然就会存在 浪费资源 的情况。 ? 这里说的浪费资源指的是资源空闲,没有充分使用的情况。 ? 操作系统为我们的程序带来了 并发性,操作系统使我们的程序同时运行多个程序,一个程序就是一个进程,也就相当于同时运行了多个进程。 操作系统是一个并发系统,并发性是操作系统非常重要的特征,操作系统具有同时处理和调度多个程序的能力,比如多个 I/O 设备同时在输入输出;设备 I/O 和 CPU 计算同时进行;内存中同时有多个系统和用户程序被启动交替、穿插地执行。操作系统在协调和分配进程的同时,操作系统也会为不同进程分配不同的资源。 操作系统实现多个程序同时运行解决了单个程序无法做到的问题,主要有下面三点 资源利用率,我们上面说到,单个进程存在资源浪费的情况,举个例子,当你在为某个文件...
- 下一篇
教你几招,快速创建 MySQL 五百万级数据
我是风筝,公众号「古时的风筝」,一个兼具深度与广度的程序员鼓励师,一个本打算写诗却写起了代码的田园码农! 文章会收录在 JavaNewBee 中,更有 Java 后端知识图谱,从小白到大牛要走的路都在里面。 如果你打算好好学习一下 MySQL,性能优化肯定是绕不过去一个问题。当你撸起袖子准备开始的时候,突然发现一个问题摆在眼前,本地数据库中没那么大的数据量啊,几条数据优化个毛线啊。生产库里数据多,但谁敢直接在生产环境动手啊,想被提前优化吗? 要知道,程序员从不轻言放弃,没有数据我们就自己创造数据嘛,new 对象这种事情可是我们的拿手好戏,对象都能 new 出来,更别说几百万条数据了。 使用官方数据 官方显然知道我们需要一些测试数据做个练习什么的,所以准备了一份测试数据给我们。可以到 https://github.com/datacharmer/test_db 上去下载,这个数据库包含约30万条员工记录和280万个薪水条目,文件大小为 167 M。 下载完成之后,直接使用 MySQL 客户端运行 sql 文件即可。 或者直接使用命令,然后输入密码导入。 mysql -u root -p ...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- 设置Eclipse缩进为4个空格,增强代码规范
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- Hadoop3单机部署,实现最简伪集群
- CentOS8编译安装MySQL8.0.19
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2整合MyBatis,连接MySql数据库做增删改查操作
- SpringBoot2整合Thymeleaf,官方推荐html解决方案