JAVA知识
**classloader
JVM装载**
在说java的ClassLoader机制之前,我先了解下jvm的装载过程和其中的原理。
装载就是寻找一个类或者一个接口的二进制形式并且用二进制形式构造代表这个类或者是这个接口的class对象的过程。
类的生命周期是从被加载到虚拟机内存中开始,到卸载出内存结束。
加载->验证->准备->解析->初始化->使用->卸载
在java中,类装载器把一个类装入java虚拟机中,要经过三个步骤完成:装载、链接和初始化
这是java的装载流程,后面要说下java中,类的表现形式。
在java中,一个类代表着这个类要执行的代码,但是这个类可以有对应的各种不同的实例,不同的实例就是通过类中数据的表示状态来区分。状态是动态的,但是代码则不会。当我们将一个特定的状态和一个类对应起来,也就是意味着将一个类实例化。尽管相同的类呢,对应的实例有各种各样不同的状态,但是其基本底层还都是同一份代码,只是其中的数据状态有不同。jvm一般只加载一次类,以后相同的类就不会再加载。
下面就讲下JVM是如何区分不同的类的:
在Java中,一个类用其完全匹配类名(fully qualified class name)作为标识,这里指的完全匹配类名包括包名和类名。但在JVM中一个类用其全名和一个加载类ClassLoader的实例作为唯一标识。因此,如果一个名为Pg的包中,有一个名为Cl的类,被类加载器KlassLoader的一个实例kl1加载,Cl的实例,即C1.class在JVM中表示为(Cl, Pg, kl1)。这意味着两个类加载器的实例(Cl, Pg, kl1) 和 (Cl, Pg, kl2)是不同的,被它们所加载的类也因此完全不同,互不兼容的。
JVM规范定义了两种类型的类装载器:启动内装载器(bootstrap)和用户自定义装载器(user-defined class loader)。
JVM在运行时会产生三个ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader。Bootstrap是用C++编写的,我们在Java中看不到它,是null,是JVM自带的类装载器,用来装载核心类库,如java.lang.*等。
AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent为Bootstrap ClassLoader。
package javatest; public class TestClassLoader{ public static void main(String[] args){ Class cl = null; ClassLoader cLoader; cLoader = ClassLoader.getSystemClassLoader(); System.out.println(cLoader); while(cLoader != null){ cLoader = cLoader.getParent(); System.out.println(cLoader); } try{ cl = Class.forName("java.lang.Object"); cLoader = cl.getClassLoader(); System.out.println("java.lang.Object loader is "+cl); cl = Class.forName("javatest.TestClassLoader"); cLoader = cl.getClassLoader(); System.out.println("LoadTest loader is "+cl); }catch(Exception e){ e.printStackTrace(); } } }
output:
sun.misc.Launcher$AppClassLoader@73d16e93
// 系统的类装载器来自类sun.misc.Launcher$AppClassLoader@73d16e93的实例化,
sun.misc.Launcher$ExtClassLoader@15db9742
// 系统的类装载器的parent来自sun.misc.Launcher$ExtClassLoader@15db9742的实例化
null
//系统的类装载器的爷爷是由上面的Bootstrap ClassLoader实例而来,但是呢,这个Bootstrap ClassLoader是由C++实现的(嘿嘿嘿,混血儿),在java中是看不到滴。
java.lang.Object loader is null
//核心类都是由Bootstrap ClassLoader进行装载滴
LoadTest loader is sun.misc.Launcher$AppClassLoader@73d16e93
//用户自己的类都是由AppClassLoader进行加载滴。
那么问题来了,JAVA为啥需要这么多类加载器(当然是多层负责每层对应的类系统,而且多态这个磨人的妖精很是厉害,需要多层加载机制进行处理。–个人理解)
因为java是动态加载类的,这样的话,用到什么类就加载什么类,不用的就不加载(模仿Linux的内存管理机制!!!也让我想起了C++里面的内存申请,如果申请内存,先不分配实际物理内存,当需要访问的时候,再进行分配内存进行操作)
点击关注阿里云科技快讯,跟多精美礼品等你来拿!
![]()
参考:兔子哥哥

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
JavaScript 编码指南
本文接下来的部分是一些JavaScript 指导方针,不是一成不变的法律。如果能够清晰解释代码含义,当然有很多的理由不这样做,但是,请保持警惕和自觉。他们能经过时间的检验也是有理由的:因为他们通常都是对的。偏离指南应该有好的理由,并不能简单因为突发奇想或者个人偏好就那么做。 基本上写作的基本准则的每一部分都能应用在代码上: 让段落成为文章的基本结构:每一段对应一个主题。 去掉无用的单词。 . 使用主动语态。 避免一连串松散的句子。 将相关的词语放在一起。 陈述句用主动语态。 平行的概念用平行的结构。 这些都可以用在我们的代码风格上。 让函数成为代码的基本单元。每个函数做一件事。 去掉无用的代码 使用主动语态 避免一连串松散结构的代码 把相关的代码放在一起。 表达式和陈述语句中使用主动语态。 用并行的代码表达并行的概念。 1、让函数成为代码的基本单元。每个函数做一件事。 软件开发的本质就是写作。我们把模块、函数、数据结构组合在一起,就有了一个软件程序。 理解如何编写函数并如何构建它们,是软件开发者的基本技能。 模块是一个或多个函数或数据结构的简单集合,数据结构是我们如何表示程序的状态,但...
- 下一篇
8月16日云栖精选夜读 | 加码投资亚太市场,阿里云区域第一优势明显
8月15日,在新加坡举办的Infinity 2018阿里云亚太峰会上,新加坡国立大学(NUS)宣布与阿里云合作推进新加坡“智慧国计划”和创新孵化器项目。双方将为年轻的科学家和技术人才提供云计算技术支持,为创业者提供向全球投资人展示其创意的平台。 热点热议 加码投资亚太市场,阿里云区域第一优势明显 作者:阿里云头条 发表在:云栖学习小组 全球发布!阿里云Serverless Kubernetes全球免费公测 作者:阿里云头条 发表在:云栖学习小组 Aliware直播培训新高度,赋能阿里专有云 作者:中间件小哥 发表在:阿里云分布式应用服务 知识整理 RocketMQ 的保险丝| Sentinel 如何通过匀速请求和冷启动来保障服务的稳定性 作者:中间件小哥 发表在:阿里云分布式应用服务 springMVC原理 作者:壹玖 手动为Kubernetes Worker节点添加实例角色 作者:初扬 服务化改造实践(一)| Dubbo + ZooKeeper 作者:中间件小哥 发表在:阿里云分布式应用服务 算法之树(二,B+树、哈夫曼树、堆、红黑树)(Java版)-持续更新补充 作者:kissjz...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7安装Docker,走上虚拟化容器引擎之路
- MySQL8.0.19开启GTID主从同步CentOS8
- 设置Eclipse缩进为4个空格,增强代码规范
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Red5直播服务器,属于Java语言的直播服务器
- SpringBoot2全家桶,快速入门学习开发网站教程
- Windows10,CentOS7,CentOS8安装Nodejs环境
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长