作为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动作,

jvm加载类(更新中)的更多相关文章

  1. JVM加载类的过程,双亲委派机制中的方法

    JVM加载类的过程: 1)JVM中类的整个生命周期: 加载=>验证=>准备=>解析=>初始化=>使用=>卸载  1.1.加载 类的加载阶段,主要是获取定义此类的二进 ...

  2. [转]jvm加载类规则

    jvm包括三种类加载器: 第一种:bootstrap classloader:加载Java的核心类. 第二种:extension classloader:负责加载jre的扩展目录中的jar包. 第三种 ...

  3. JVM学习(二)JVM加载类

    一.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构 ...

  4. 自动加载类PHP中spl_autoload_register函数的用法

    spl_autoload_register(PHP 5 >= 5.1.2) spl_autoload_register — 注册__autoload()函数 说明bool spl_autoloa ...

  5. JVM加载类冲突,导致Mybatis查数据库返回NULL的一个小问题

    今天碰到个bug,虽然小,但是有点意思 背景是SpringMVC + Mybatis的一个项目,mapper文件里写了一条sql 大概相当于 select a from tableA where b ...

  6. JVM加载类的原理机制

    在Java中,类装载器把一个类装入Java虚拟机中,要经过三个步骤来完成:装载.链接和初始化,其中链接又可以分成校验.准备.解析装载:查找和导入类或接口的二进制数据: 链接:执行下面的校验.准备和解析 ...

  7. jvm加载类的7个步骤

  8. 虚拟机(JVM)如何加载类

    首先JVM加载类的一般流程分三步: 加载 链接 初始化 那么是否全部Java类都是这样三步走的方式加载呢?我们可以从Java的数据类型去出发.Java分基本类型和引用类型.其中按照面向对象的特性,一切 ...

  9. JVM加载class文件的原理

    当Java编译器编译好.class文件之后,我们需要使用JVM来运行这个class文件.那么最开始的工作就是要把字节码从磁盘输入到内存中,这个过程我们叫做[加载 ].加载完成之后,我们就可以进行一系列 ...

随机推荐

  1. nodejs的dependency.md

    dependency和devDependency的区别 package-a --- package-b (dependency) --- | --- package-c (devDependency) ...

  2. 关于set和map迭代器支持的运算

    问题: 曾经想遍历一个set遍历.当时是这样写的: set<int>::iterator b = a.begin()+1 后来发现程序报错.究其原因是,set迭代器不支持加减数操作. 查看 ...

  3. 将实体类、匿名对象转换为SqlParameter列表

    /// <summary> /// <remarks> /// <para>将实体类/匿名对象转换为SqlParameter列表</para> /// ...

  4. vs 2013 编译cocos2d-x-3.9

    下载地址:链接: https://pan.baidu.com/s/1IkQsMU6NoERAAQLcCUMcXQ 提取码: p1pb 下载完成后,解压 进入build 目录 使用vs 2013 打开工 ...

  5. JAVA 面向对象中的多态

    多态是继封装.继承之后,面向对象的第三大特性. 现实事物经常会体现出多种形态,如学生,学生是人的一种,则一个具体的同学张三既是学生也是人,即出现两种形态. Java作为面向对象的语言,同样可以描述一个 ...

  6. 删除GitHub或者GitLab 上的文件夹,git rm -r --ceched 文件夹名 ,提交commit,git push

    方法一 这里以删除 .setting 文件夹为案例 git rm -r --cached .setting #--cached不会把本地的.setting删除 git commit -m 'delet ...

  7. Rxbus的使用

    Rxbus是一种模式,在RxJava中 一.添加依赖 compile 'io.reactivex:rxandroid:1.2.0' compile 'io.reactivex:rxjava:1.1.5 ...

  8. 你真的了解restful api吗?

    前言 在以前,一个网站的完成总是“all in one”,页面,数据,渲染全部在服务端完成,这样做的最大的弊端是后期维护,扩展极其痛苦,开发人员必须同时具备前后端知识.于是慢慢的后来兴起了前后端分离的 ...

  9. Lua和C++交互 学习记录之九:在Lua中以面向对象的方式使用C++注册的类

    主要内容转载自:子龙山人博客(强烈建议去子龙山人博客完全学习一遍) 部分内容查阅自:<Lua 5.3  参考手册>中文版 译者 云风 制作 Kavcc vs2013+lua-5.3.3 在 ...

  10. 日常英语---六、Maplestory Illium

    日常英语---六.Maplestory Illium 一.总结 一句话总结: maplestory-['meiplstɔri]  illium-镍铬合金 ['meiplstɔri]  n. 枫之谷(网 ...