zoukankan      html  css  js  c++  java
  • 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动作,










  • 相关阅读:
    将oh-my-zsh编程真正的my zsh
    Linux Shell 程序调试
    (64位)本体学习程序(ontoEnrich)系统配置说明文档
    Shell编程——vim常用命令
    Morris Traversal 方法遍历二叉树(非递归、不用栈,O(1)空间)
    206. Reverse Linked List
    欧几里德算法求解最大公约数
    25. Reverse Nodes in k-Group
    86. Partition List
    24. Swap Nodes in Pairs
  • 原文地址:https://www.cnblogs.com/allenwas3/p/6846889.html
Copyright © 2011-2022 走看看