[讨论] 自由讨论帖/建议帖/资料补充帖/马克帖(谢绝纯水)

RednaxelaFX 2013-07-17
stevenlye 写道
谢谢回复!看了你上面给的链接,对那个pdf做的ppt里面oop与klass的关系还是不太清楚,这两个结构各自都存的是什么信息,它们都在堆上存储吗?这个pdf中的130页到132页讲类加载的部分怎么没有东西呢?还有个instanceKlassHandle结构,这个是干嘛的,没找到它的具体定义

所有oop是oopDesc*。所有oopDesc及子类的实例的开头都有指向klassOopDesc的指针(有可能是直接指针也有可能是压缩指针)。

oopDesc存一个对象自身的实例数据;它引用的klassOopDesc存这个类型的对象都共享的元数据。

从GC的角度来说oopDesc和klassOopDesc的实例都保存在GC堆上。但从Java程序员的角度来看元数据的部分(包括klassOopDesc在内)不是存在Java堆上。所谓的PermGen虽然是GC堆的一部分,但不是Java堆的一部分。

类加载的部分写起来好麻烦我当时还没想好怎么写所以留空了呃呵呵…

xxxHandle这些用是用宏来定义的。在handles.hpp
stevenlye 2013-07-17
Hotspot中的类加载时用的双亲委派模型吗?如果我自己写的一个程序里面有好几个类,这些类的加载过程是怎样的呢,最开始是系统类加载器接手,然后向双亲委派吗?
RednaxelaFX 2013-07-17
stevenlye 写道
Hotspot中的类加载时用的双亲委派模型吗?如果我自己写的一个程序里面有好几个类,这些类的加载过程是怎样的呢,最开始是系统类加载器接手,然后向双亲委派吗?

用的。不过parent delegation机制其实不是在HotSpot VM内,而是在JDK里的Java标准库实现的,用Java代码来实现就够了。HotSpot VM内部只实现了bootstrap class loader。

在OpenJDK系的JDK实现(包括Oracle JDK)里,一般Java应用启动之后system class loader是sun.misc.Launcher$AppClassLoader;它的parent是extension class loader,具体是sun.misc.Launcher$ExtClassLoader。再往上就是bootstrap class loader了。

System class loader和extension class loader里parent delegation机制其实就靠java.lang.ClassLoader.loadClass(String name)里的代码来实现。参考它的代码就好了。看这里的314行:http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/d3912e74ec28/src/share/classes/java/lang/ClassLoader.java
stevenlye 2013-07-18
RednaxelaFX 写道
stevenlye 写道
Hotspot中的类加载时用的双亲委派模型吗?如果我自己写的一个程序里面有好几个类,这些类的加载过程是怎样的呢,最开始是系统类加载器接手,然后向双亲委派吗?

用的。不过parent delegation机制其实不是在HotSpot VM内,而是在JDK里的Java标准库实现的,用Java代码来实现就够了。HotSpot VM内部只实现了bootstrap class loader。

在OpenJDK系的JDK实现(包括Oracle JDK)里,一般Java应用启动之后system class loader是sun.misc.Launcher$AppClassLoader;它的parent是extension class loader,具体是sun.misc.Launcher$ExtClassLoader。再往上就是bootstrap class loader了。

System class loader和extension class loader里parent delegation机制其实就靠java.lang.ClassLoader.loadClass(String name)里的代码来实现。参考它的代码就好了。看这里的314行:http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/d3912e74ec28/src/share/classes/java/lang/ClassLoader.java


也就是说一般Java应用启动之后system class loader开始调用java.lang.ClassLoader.loadClass(String name)方法开始向parent委托加载,bootstrap class loader和extension class loader检查发现不是自己可以加载的类,最终还是返回到system class loader自己加载呢?

System class loader和extension class loader的实现上是共用java.lang.ClassLoader.loadClass(String name)方法来加载类,其中用到的对class文件的解析方法也是一样的吗?而bootstrap class loader是自己独立的一套加载方法,是hotspot/src/share/vm/classfile文件下的cpp代码实现的吗?

还有这三种类加载器怎么判断哪些类应该是自己加载的,哪些不是呢?

多谢楼主的回复了,我刚研究这个,有很多问题,而且有些问题比较小白,楼主别介意啊。。。
RednaxelaFX 2013-07-19
stevenlye 写道
也就是说一般Java应用启动之后system class loader开始调用java.lang.ClassLoader.loadClass(String name)方法开始向parent委托加载,bootstrap class loader和extension class loader检查发现不是自己可以加载的类,最终还是返回到system class loader自己加载呢?

在OpenJDK系的JDK实现里,AppClassLoader和ExtClassLoader都没override掉java.lang.ClassLoader.loadClass(),也就是使用继承的loadClass()方法。
这个方法里就实现了parent delegation机制,你看代码应该很清楚。前面回复的链接里,314行就是向parent发出委派的地方。如果parent是null则意味着parent是bootstrap class loader,这个时候就用findBootstrapClass0

stevenlye 写道
System class loader和extension class loader的实现上是共用java.lang.ClassLoader.loadClass(String name)方法来加载类,其中用到的对class文件的解析方法也是一样的吗?

对的。具体负责把byte[]给parse成JVM内部能识别的Class,这是在ClassLoader.defineClass()方法做的。这个方法由JVM内部直接实现。在HotSpot VM里就是你已经看到了的SystemDictionary -> ClassFileParser做的。

stevenlye 写道
而bootstrap class loader是自己独立的一套加载方法,是hotspot/src/share/vm/classfile文件下的cpp代码实现的吗?

其实从defineClass()开始下面的逻辑都是所有ClassLoader共享的,包括bootstrap class loader。这个loader跟其它Java层的class loader相比最大的不同是它能加载的类的路径由-Xbootclasspath指定,默认只用来加载JDK内部的类(像java.lang.Object、java.lang.String之类)。

stevenlye 写道
还有这三种类加载器怎么判断哪些类应该是自己加载的,哪些不是呢?

根据parent delegation的默认逻辑,反正先交给parent加载,如果parent能加载就没自己啥事了;判断自己能否加载就看是否能找得到(findClass()),能的就自己加载,找不到的就抛ClassNotFoundException。如果交给parent加载而parent抛了异常那就可以知道应该尝试自己加载。

“找得到”通常跟这个ClassLoader能访问什么路径相关。例如system class loader能访问的路径就是-classpath参数指定的。
stevenlye 2013-07-20
多谢你的指导!大哥你太牛了,要是学校的老师都像你这样很有研究,我们这群苦逼的学生就苦逼的有价值了。。。我在看看想想,遇到什么问题在贴上来向你请教
stevenlye 2013-07-20
源码里面findBootstrapClass0调用的native Class findBootstrapClass,这个native Class的实现在哪里,从sourceinsight跳不过去了。这种native Class的方法还挺多的,还有defineClass0,resolveClass0。。。

还有就是findBootstrapClass与defineClass之间有调用关系吗?还是它们之间是独立的,只是到最后将byte[]转化成JVM内部的class时都是调用ClassFileParse来完成的呢?

RednaxelaFX 2013-07-20
stevenlye 写道
源码里面findBootstrapClass0调用的native Class findBootstrapClass,这个native Class的实现在哪里,从sourceinsight跳不过去了。这种native Class的方法还挺多的,还有defineClass0,resolveClass0。。。

SourceInsight确实会拿这种没办法吧。请参考之前的帖:
http://hllvm.group.iteye.com/group/topic/35385#post-236056
http://hllvm.group.iteye.com/group/topic/37604#post-243981

stevenlye 写道
还有就是findBootstrapClass与defineClass之间有调用关系吗?还是它们之间是独立的,只是到最后将byte[]转化成JVM内部的class时都是调用ClassFileParse来完成的呢?

findBootstrapClass(name)会委托bootstrap class loader加载name指定的名字的类,如果bootstrap class loader能找到那个类,就会自行加载,不会向上调用回Java这边的defineClass()。不过底下都会经过SystemDictionary和ClassFileParser。
stevenlye 2013-07-22
请问handle与oop、klass的关系具体是怎样的?handle的作用是什么?
RednaxelaFX 2013-07-22
stevenlye 写道
请问handle与oop、klass的关系具体是怎样的?handle的作用是什么?

我之前在这里写过了,请参考:http://rednaxelafx.iteye.com/blog/1044951
Global site tag (gtag.js) - Google Analytics