虚拟机如何处理装载类失败的情况
simpleman7210
2013-09-10
如果虚拟机在装载一个类C的时候失败了,比如C没有找到,或者解析C的时候遇到格式或数据错误,或者C的super class没有找到或解析出错,那么,以后还会不会重新尝试装载C或者其super class呢?
举个例子,执行某些字节码指令,会触发对类的装载,比如new指令,getstatic, putstatic等,倘若在装载的过程中遇到错误,以后再执行到这样的指令时,会不会重新尝试装载呢?还是直接抛出错误(以前的解析错误被记录了)?虚拟机规范对此有没有什么说法或要求。 |
|
RednaxelaFX
2013-09-10
楼主的问题,一部分可以由用户定制,而一部分写死在VM里。
自定义ClassLoader如果覆写了loadClass()/findClass(),那么可以在里面自定义“找不到类”的情况下要不要记录在自己里面以便以后不重复加载。这个还没到JVM那层,所以JVM管不着。 但楼主想问的多半不是这个。 楼主关心的功能在这里:(JDK 6的HotSpot VM) constantPoolOopDesc::klass_at_impl() // The original attempt to resolve this constant pool entry failed so find the // original error and throw it again (JVMS 5.4.3). if (in_error) { symbolOop error = SystemDictionary::find_resolution_error(this_oop, which); guarantee(error != (symbolOop)NULL, "tag mismatch with resolution error table"); ResourceMark rm; // exception text will be the class name const char* className = this_oop->unresolved_klass_at(which)->as_C_string(); THROW_MSG_0(error, className); } 也就是HotSpot VM是记录了resolution error的,在SystemDictionary里有个resolution_errors表;后面再尝试resolve的时候会把记录下来的异常抛出去。 对应的JVM规范规定是:http://docs.oracle.com/javase/specs/jvms/se5.0/html/ConstantPool.doc.html#73492 JVM Spec, 2nd Edition 写道 Subsequent attempts to resolve a symbolic reference that the Java virtual machine has previously unsuccessfully attempted to resolve always fails with the same error that was thrown as a result of the initial resolution attempt.
新版JVM规范里这部分规定还是在5.4.3:http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4.3 |
|
simpleman7210
2013-09-10
谢谢指出来。原来JVM规范对此真有要求。
|