一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第5天,点击查看活动详情。
字节码加载
方法区
作用:
- 在内存中,存放class文件的逻辑结构,也就是类的元(meta)信息
包括:
- 常量池,类信息,字段,方法,属性等
方法区的实现
JVM只是一个规范,所以方法区也只是一个规范,有不同实现方式:
- 在java8以前的版本,被实现“永久代”,名称与堆中的“年轻代”,“老年代”相对应和堆一样,同为线程共有,但又没有垃圾回收,所以被称为“非堆”
- 在java8以后的版本,被称为元空间(meta space),直接放在本地内存,所以理论上没有大小限制。
Java程序的双亲委派模型
- BootstrapClassLoader 启动类加载器,jvm内部C++实现,无法获取
- ExtensionClassLoader 扩展类加载器
- ApplicationClassLoader 应用程序类加载器
类加载的过程:
每个ClassLoader实例都有一个父类加载器的引用(不是继承的关系,是一个组合包含的关系)虚拟机内置的类加载器(Bootstrap ClassLoader)本身没有父类加载器,但可以用作其它ClassLoader实例的的父类加载器。当一个ClassLoader实例需要加载某个类时,它会试图亲自搜索某个类之前,先把这个任务委托给它的父类加载器,这个过程是由上至下依次检查的,首先由最顶层的类加载器Bootstrap ClassLoader试图加载,如果没加载到,则把任务转交给Extension ClassLoader试图加载,如果也没加载到,则转交给ApplicationClassLoader进行加载,如果它也没有加载得到的话,则返回给委托的发起者,由它到指定的文件系统或网络等URL中加载该类。如果它们都没有加载到这个类时,则抛出ClassNotFoundException异常。否则将这个找到的类生成一个类的定义,并将它加载到内存当中,最后返回这个类在内存中的Class实例对象。
Android程序的双亲委派模型
ClassLoader源码
//真正从字节码文件中根据类名,返回class实例的方法,应该被子类实现或者重写
protected Class<?> findClass(String name) throws ClassNotFoundException {
throw new ClassNotFoundException(name);
}
loadClass方法
//外部通过这个方法获取class的实例
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
Class<?> c = findLoadedClass(name);//已经被加载的类直接返回结果
if (c == null) {
try {
if (parent != null) {
c = parent.loadClass(name, false);//递归调用父类加载器的loadclass
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
}
if (c == null) {
c = findClass(name);
}
}
return c;
}
加载自己写的Object类
class的双亲委派模型的好处
- 能够对类划分优先级层次关系
- 避免类的重复加载
- 沙箱安全机制,避免代码被篡改