ClassLoader小知识

JVM由4大部分组成:ClassLoader,Runtime Data Area,Execution Engine,Native Interface。

栈帧包含三类信息:局部变量,执行环境,操作数栈。

对比java的基本数据类型,jvm的规范中没有boolean类型。这是因为jvm中堆boolean的操作是通过int类型来进行处理的,而boolean数组则是通过byte数组来进行处理。

通过查阅jvm指令集和其对应的数据类型的关系发现,大部分的指令都没有支持整数类型byte、char和short,甚至没有任何指令支持boolean类型。编译器会在编译期或运行期会将byte和short类型的数据带符号扩展(Sign-Extend)为相应的int类型数据,将boolean和char类型数据零位扩展(Zero-Extend)为相应的int类型数据。与之类似的,在处理boolean、byte、short和char类型的数组时,也会转换为使用对应的int类型的字节码指令来处理。因此,大多数对于boolean、byte、short和char类型数据的操作,实际上都是使用相应的对int类型作为运算类型(Computational Type)。

可以做为GC root(根对象)的对象有以下几种:

  • 虚拟机栈(栈帧中变量引用的对象)
  • 方法区中静态属性(static 属性)
  • 方法区中的常量(static final),(jdk8及以上,为元数据区)
  • 本地方法栈中引用的对象

JVM 运行并不是一次性加载所需要的全部类的,它是按需加载,也就是延迟加载。程序在运行的过程中会逐渐遇到很多不认识的新类,这时候就会调用 ClassLoader 来加载这些类。加载完成后就会将 Class 对象存在 ClassLoader 里面,下次就不需要重新加载了。

程序在运行过程中,遇到了一个未知的类,它会选择哪个 ClassLoader 来加载它呢?虚拟机的策略是使用调用者 Class 对象的 ClassLoader 来加载当前未知的类。何为调用者 Class 对象?就是在遇到这个未知的类时,虚拟机肯定正在运行一个方法调用(静态方法或者实例方法),这个方法挂在哪个类上面,那这个类就是调用者 Class 对象。前面我们提到每个 Class 对象里面都有一个 classLoader 属性记录了当前的类是由谁来加载的。

因为 ClassLoader 的传递性,所有延迟加载的类都会由初始调用 main 方法的这个 ClassLoader 全全负责,它就是 AppClassLoader。

ClassLoader遇到不认识的类,就会去加载loadClass,但是不是直接加载,而是先查找ClassLoader有没有加载过这个类记录,如果没有记录则交给父ClassLoader来加载,层层往上委托,如果父ClassLoader加载不了,就层层向下分派findClass。因此重写loadClass会破坏双亲委派,重写findClass可以自定义类加载器的class资源来源,但是需要注意的是findClass中得到byte[]后,需要调用defineClass来定义这个类。

同一个class文件通过不同ClassLoader加载出来的类,调用equals方法返回false。因为ClassLoader加载class文件后,在内存中申请一片空间来存储class的信息,同一个ClassLoader加载以个class文件会返回已保存的class,则地址相同;不同ClassLoader加载后,会分别申请空间来保存class信息,因此地址不同。

双亲委派模型的好处:
由于ClassLoader加载Class后会将Class保存在ClassLoader里面,那么不同子ClassLoader共享所有父ClassLoader里面的Class。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值