• jvm加载类(更新中)


    作为jvm的用户,从使用者角度来看,我们给jvm输入一个class文件,得到了一个Class对象。
    我们可以猜想下jvm加载类的过程:
    class文件有规定的格式,jvm去解析class文件流,读magic, major version, minor version等值(最简单的举例),然后生成Klass对象,并放到一个map中。

    首先有个全局的认识,jvm把已加载的类放在一个hashtable中。
    class SystemDictionary : AllStatic {
        // Hashtable holding loaded classes.
      static Dictionary*            _dictionary;
    };

    从java.lang.ClassLoader接口的defineClass1方法作为入口,探究类加载的过程;
    --> java.lang.ClassLoader/defineClass1

    在ClassLoader.c文件中找到Java_java_lang_ClassLoader_defineClass1;
    --> JNIEXPORT jclass JNICALL
        Java_java_lang_ClassLoader_defineClass1(JNIEnv *env, jobject loader,jstring name,jbyteArray data,jint offset,jint length,jobject pd,jstring source)

    --> ./hotspot/src/share/vm/prims/jvm.cpp:1049 JVM_DefineClassWithSource

    --> jvm.cpp/jvm_define_class_common

    --> Klass* k = SystemDictionary::resolve_from_stream(class_name, class_loader,protection_domain, &st,verify != 0,CHECK_NULL);
                                                        
        --> instanceKlassHandle k = ClassFileParser(st).parseClassFile(class_name,loader_data,protection_domain,parsed_name,verify,THREAD);    
            // We can now create the basic Klass* for this klass
            --> _klass = InstanceKlass::allocate_instance_klass(loader_data,vtable_size,itable_size,info.static_field_size,total_oop_map_size2,rt,name,super_klass(),                                            !host_klass.is_null(), CHECK_(nullHandle));
                --> ik = new (loader_data, size, THREAD) InstanceKlass( //这里用到了operator new的语法
                            vtable_len, itable_len, static_field_size, nonstatic_oop_map_size, rt, access_flags, is_anonymous);
                    --> set_init_state(InstanceKlass::allocated); //状态1

        --> define_instance_class(k, THREAD);
            --> add_to_hierarchy(k, CHECK);
                --> k->set_init_state(InstanceKlass::loaded); //状态2
            --> k->eager_initialize(THREAD);
                --> eager_initialize_impl(this_oop);
                    --> link_class_impl(this_oop, true, THREAD);  //这里主要是link操作
                        --> this_oop->set_init_state(linked); //状态3
                                                            

                                                  
    InstanceKlass中的枚举:
    enum ClassState {
        allocated,                          // allocated (but not yet linked)
        loaded,                             // loaded and inserted in class hierarchy (but not linked yet)
        linked,                             // successfully linked/verified (but not initialized yet)
        being_initialized,                  // currently running class initializer
        fully_initialized,                  // initialized (successfull final state)
        initialization_error                // error happened during initialization
    };

    //设置类加载过程的状态,通过跟踪这个方法,能大概定位类加载的过程。
    void set_init_state(ClassState state);



    allocate:
      parse class文件流,创建Klass对象,并赋属性值,在这个过程中会对class文件做简单的verify。
      常量池的解析也是在这一步。
    load
      具体的操作好像并不多,只是加到SystemDictionary中而已。
    link
      从当前类的父类开始,然后是接口,最后才是当前类;
      verify 动作,是针对Klass对象,好像是对字节码指令的合法性做校验;
      rewrite动作,










  • 相关阅读:
    NanoProfiler
    NanoProfiler
    Open Source Cassandra Gitbook for Developer
    Android Fragment使用(四) Toolbar使用及Fragment中的Toolbar处理
    Android Fragment使用(三) Activity, Fragment, WebView的状态保存和恢复
    Android Fragment使用(二) 嵌套Fragments (Nested Fragments) 的使用及常见错误
    Android Fragment使用(一) 基础篇 温故知新
    Set up Github Pages with Hexo, migrating from Jekyll
    EventBus源码解析 源码阅读记录
    Android M Permission 运行时权限 学习笔记
  • 原文地址:https://www.cnblogs.com/allenwas3/p/6846889.html
Copyright © 2020-2023  润新知