有关jvm的启动加载和类加载器的问题

Bug开发攻城狮 2017-05-31 02:12:22
1.jvm启动时第一个调用的是哪个类、哪个方法?
比如
  public class A{
public static void main(String[] args){
new A().method1();
}

public void method1(){
syso("method1 be call");
}
}

然后,我们在main方法了调用new A().method1(); 控制台就会输出 method1 be call 了。
这个过程中,我们都知道,首先是jvm读取A.class,然后用类加载器进行加载,然后用newInstance()获得A类的实例,然后去调用method1()方法,最终输出"method1 be call"
我想知道,这个第一步 ”jvm获取A.class“,jvm启动后,调用的第一个类是哪个类、哪个方法(很可能是native的),然后做了什么操作才知道去读取A.class ?

2.jvm的三个加载器,加载范围是在什么地方进行限定的?为什么要有三个加载器
jvm有三个类加载器,appClassLoader、extClassLoader、bootstrapClassLoader,分别对应加载java.class.path路径/jre的ext目录/jre的目录下的jar
这个范围的区分,是什么地方规定的?为什么要这么区分呢?
还要,我觉得其实只要两个类加载器就可以了啊,一个appClassLoader,负责加载程序员编写的类的加载,一个bootstrapClassLoader,负责加载jre目录下的所有的jar,
如果还要特殊要求的话,程序员自己继承classLoader写自己的类加载器不就好了,那extClassLoader存在是因为什么呢(jdk的编写者肯定比我聪明,这些我想到的他肯定也想到了)

哪位前辈对这两个问题有思考过,求解
...全文
413 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Bug开发攻城狮 2017-08-23
  • 打赏
  • 举报
回复
引用 3 楼 zy_281870667 的回复:
[quote=引用 2 楼 HinanaiTenshi 的回复:] 关于问题1,应该是没有标准答案的。 实际上jvm启动会做很多工作,而且不同的jvm启动的时候做的事情在底层实现上有相当大的区别,jvm规范没有也没必要规定哪个class或者哪个方法一定要被首先加载。 关于问题2,这么区分主要考虑到系统结构的解耦。 bootstrap loader作为jvm核心的核心,需要足够的稳定性和权威性,是唯一的不可替代不可重复的加载,被它加载的类无论从哪个loader里去询问,都会得到已被加载的提示,因此被明确的划分出来和其他loader区分。另外由于它是基础加载器,大多数版本jvm的bootstrap loaer都不是java或者不是纯java的实现。 而extload只是标准资源的加载,和app loader的区别在于它是java的通用加载器而已。从某种程度上说,它和ext loader的性质更加相似一些。
问题一,我们就暂以hotspot为标准吧,我找了很长时间,应该是sun.misc.lunch类的优先级非常高,因为appClassLoader和extClassLoader都是在lunch.class中(况且,lunch,一看这名字就知道是启动必须加载的类啊,哈哈) 问题二,你说的挺好的,是因为解耦,并且bootStrapClassLoader也不是java实现的。 但是,我好奇这三个类加载器区域的划分,是在什么地方写的。因为我自定义了一个加载器,我在程序里指定我自定义的加载器来加载类A,但是,会被appClassLoader抢先注册,根本就不调我自定义的类加载器(虽然现在更换路径就调我自定义的了)[/quote] 关于问题二,bootStrapClassLoader和extClassLoader加载哪些路径下的类,都是在类里硬编码了的,
业余草 2017-06-03
  • 打赏
  • 举报
回复
谢邀! 这个问题太过复杂。我也是奔着学习来的。 分享一篇鸡汤:http://www.codedq.net/blog/articles/215.html
Bug开发攻城狮 2017-05-31
  • 打赏
  • 举报
回复
引用 2 楼 HinanaiTenshi 的回复:
关于问题1,应该是没有标准答案的。 实际上jvm启动会做很多工作,而且不同的jvm启动的时候做的事情在底层实现上有相当大的区别,jvm规范没有也没必要规定哪个class或者哪个方法一定要被首先加载。 关于问题2,这么区分主要考虑到系统结构的解耦。 bootstrap loader作为jvm核心的核心,需要足够的稳定性和权威性,是唯一的不可替代不可重复的加载,被它加载的类无论从哪个loader里去询问,都会得到已被加载的提示,因此被明确的划分出来和其他loader区分。另外由于它是基础加载器,大多数版本jvm的bootstrap loaer都不是java或者不是纯java的实现。 而extload只是标准资源的加载,和app loader的区别在于它是java的通用加载器而已。从某种程度上说,它和ext loader的性质更加相似一些。
问题一,我们就暂以hotspot为标准吧,我找了很长时间,应该是sun.misc.lunch类的优先级非常高,因为appClassLoader和extClassLoader都是在lunch.class中(况且,lunch,一看这名字就知道是启动必须加载的类啊,哈哈) 问题二,你说的挺好的,是因为解耦,并且bootStrapClassLoader也不是java实现的。 但是,我好奇这三个类加载器区域的划分,是在什么地方写的。因为我自定义了一个加载器,我在程序里指定我自定义的加载器来加载类A,但是,会被appClassLoader抢先注册,根本就不调我自定义的类加载器(虽然现在更换路径就调我自定义的了)
HinanaiTenshi 2017-05-31
  • 打赏
  • 举报
回复
关于问题1,应该是没有标准答案的。 实际上jvm启动会做很多工作,而且不同的jvm启动的时候做的事情在底层实现上有相当大的区别,jvm规范没有也没必要规定哪个class或者哪个方法一定要被首先加载。 关于问题2,这么区分主要考虑到系统结构的解耦。 bootstrap loader作为jvm核心的核心,需要足够的稳定性和权威性,是唯一的不可替代不可重复的加载,被它加载的类无论从哪个loader里去询问,都会得到已被加载的提示,因此被明确的划分出来和其他loader区分。另外由于它是基础加载器,大多数版本jvm的bootstrap loaer都不是java或者不是纯java的实现。 而extload只是标准资源的加载,和app loader的区别在于它是java的通用加载器而已。从某种程度上说,它和ext loader的性质更加相似一些。
Bug开发攻城狮 2017-05-31
  • 打赏
  • 举报
回复
怎么没人啊 呼唤高手啊 @执笔记忆的空白 @HinanaiTensh @业余草

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧