[讨论] 关于GeneratedMethodAccessor的一点疑问
巴海和
2014-07-31
在OpenJDK 6下反射调用生成的”GeneratedMethodAccessor+数字“类是由JVM直接生成到内存里?还是需要通过Java层次的类加载器进行加载?如果通过类加载器进行加载的话,是通过哪个类加载器呀?
我已经阅读过这两篇文章了,只是还有上述疑问,求解答,3ks。 http://rednaxelafx.iteye.com/blog/548536 http://rednaxelafx.iteye.com/blog/727938 |
|
nijiaben
2014-07-31
巴海和 写道 在OpenJDK 6下反射调用生成的”GeneratedMethodAccessor+数字“类是由JVM直接生成到内存里?还是需要通过JAVA层次的类加载器进行加载?如果通过类加载器进行加载的话,是通过哪个类加载器呀?
我已经阅读过这两篇文章了,只是还有上述疑问,求解答,3ks。 http://rednaxelafx.iteye.com/blog/548536 http://rednaxelafx.iteye.com/blog/727938 通过method的定义类加载器加载的, 详情见 private MagicAccessorImpl generate(final Class declaringClass, String name, Class[] parameterTypes, Class returnType, Class[] checkedExceptions, int modifiers, boolean isConstructor, boolean forSerialization, Class serializationTargetClass) { //class字节码构建过程略 return AccessController.doPrivileged( new PrivilegedAction<MagicAccessorImpl>() { public MagicAccessorImpl run() { try { return (MagicAccessorImpl) ClassDefiner.defineClass (generatedName, bytes, 0, bytes.length, declaringClass.getClassLoader()).newInstance(); } catch (InstantiationException e) { throw (InternalError) new InternalError().initCause(e); } catch (IllegalAccessException e) { throw (InternalError) new InternalError().initCause(e); } } }); } 其中declaringClass.getClassLoader()就是method的定义类的类加载器 static Class defineClass(String name, byte[] bytes, int off, int len, final ClassLoader parentClassLoader) { ClassLoader newLoader = AccessController.doPrivileged( new PrivilegedAction<ClassLoader>() { public ClassLoader run() { return new DelegatingClassLoader(parentClassLoader); } }); return unsafe.defineClass(name, bytes, off, len, newLoader, null); } 实则通过unsafe.defineClass来定义类,类的字节流已经有了,直接传到了jvm里的如下方法进行类的定义 klassOop SystemDictionary::resolve_from_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, bool verify, TRAPS) 而上述的class_loader就是上面的defineClass返回的DelegatingClassLoader对象,但是在jvm里会使用代理的parentClassLoader来进行类定义 oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) { if (loader != NULL) { // See whether this is one of the class loaders associated with // the generated bytecodes for reflection, and if so, "magically" // delegate to its parent to prevent class loading from occurring // in places where applications using reflection didn't expect it. klassOop delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass(); // This might be null in non-1.4 JDKs if (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)) { return parent(loader); } } return loader; } |
|
巴海和
2014-08-01
nijiaben 写道 巴海和 写道 在OpenJDK 6下反射调用生成的”GeneratedMethodAccessor+数字“类是由JVM直接生成到内存里?还是需要通过JAVA层次的类加载器进行加载?如果通过类加载器进行加载的话,是通过哪个类加载器呀?
我已经阅读过这两篇文章了,只是还有上述疑问,求解答,3ks。 http://rednaxelafx.iteye.com/blog/548536 http://rednaxelafx.iteye.com/blog/727938 通过method的定义类加载器加载的, 详情见 private MagicAccessorImpl generate(final Class declaringClass, String name, Class[] parameterTypes, Class returnType, Class[] checkedExceptions, int modifiers, boolean isConstructor, boolean forSerialization, Class serializationTargetClass) { //class字节码构建过程略 return AccessController.doPrivileged( new PrivilegedAction<MagicAccessorImpl>() { public MagicAccessorImpl run() { try { return (MagicAccessorImpl) ClassDefiner.defineClass (generatedName, bytes, 0, bytes.length, declaringClass.getClassLoader()).newInstance(); } catch (InstantiationException e) { throw (InternalError) new InternalError().initCause(e); } catch (IllegalAccessException e) { throw (InternalError) new InternalError().initCause(e); } } }); } 其中declaringClass.getClassLoader()就是method的定义类的类加载器 static Class defineClass(String name, byte[] bytes, int off, int len, final ClassLoader parentClassLoader) { ClassLoader newLoader = AccessController.doPrivileged( new PrivilegedAction<ClassLoader>() { public ClassLoader run() { return new DelegatingClassLoader(parentClassLoader); } }); return unsafe.defineClass(name, bytes, off, len, newLoader, null); } 实则通过unsafe.defineClass来定义类,类的字节流已经有了,直接传到了jvm里的如下方法进行类的定义 klassOop SystemDictionary::resolve_from_stream(Symbol* class_name, Handle class_loader, Handle protection_domain, ClassFileStream* st, bool verify, TRAPS) 而上述的class_loader就是上面的defineClass返回的DelegatingClassLoader对象,但是在jvm里会使用代理的parentClassLoader来进行类定义 oop java_lang_ClassLoader::non_reflection_class_loader(oop loader) { if (loader != NULL) { // See whether this is one of the class loaders associated with // the generated bytecodes for reflection, and if so, "magically" // delegate to its parent to prevent class loading from occurring // in places where applications using reflection didn't expect it. klassOop delegating_cl_class = SystemDictionary::reflect_DelegatingClassLoader_klass(); // This might be null in non-1.4 JDKs if (delegating_cl_class != NULL && loader->is_a(delegating_cl_class)) { return parent(loader); } } return loader; } method的定义类的类加载器是从哪里来的?另外,您的意思是上述生成的类是直接由JVM使用对应的字节流在内存里展开?不需要经过类加载器进行加载?3ks |
|
nijiaben
2014-08-01
巴海和 写道 method的定义类的类加载器是从哪里来的? 你当初获取method的时候不是通过class得到的吗,每个class都有一个定义类加载器,也就是在那个classloader的classpath里是存在那个类的(当然也可能动态创建,类似反射的这种情况) 巴海和 写道 另外,您的意思是上述生成的类是直接由JVM使用对应的字节流在内存里展开?不需要经过类加载器进行加载?3ks 字节流在java层面构建,直接走jvm里通过字节流定义类的方法,并不需要走java层面的类加载器的loadClass方法来获取字节码流 |