JVM工作过程

文章目录


JVM工作过程

JVM运行的过程涉及三个子系统:

  • 类装载子系统(Class loader SubSys)
  • 运行时数据区(Running Data Areas)
  • 执行引擎(Execution Engine)
    JVM工作过程

类加载子系统

-作用是将字节码文件加载到JVM中,在类第一次被使用的时候,需要初始化文件。

  • 装载:功能就是加载类,使用到了三个类加载器。
    Bootstrap ClassLoader 启动类加载器
    Extension ClassLoader执行类加载器
    Application ClassLoader应用来加载器
  • 链接:
    验证:字节码验证器将验证生成字节码是否正确,如果验证失败,将得到验证错误。
    准备:对于所有的静态变量,进行i分配内存并给默认值分配内存,并给默认值null
    解析:将所有的符号内存引用替换为方法区的原始引用初始化,静态变量将被赋予原始值,静态代码块将被执行。

运行时数据区域

  • 方法区:类级别数据、静态变量的应用,线程共享。
  • 堆区:对象及其实例变量和数据的存储位置,线程共享。
  • 栈区:程序运行过程中使用栈区,线程私有。
  • 本地方法栈:保存本地方法的信息,调用JNI(java 本地接口),线程私有。
  • 程序计数器:线程私有。

执行引擎

  1. 将分配给运行时数据区域的字节码将由执行引擎来执行,执行引擎读取字节码并逐个进行执行。

类加载器

负责将字节码加载到内存中。
JVM工作过程
2. Bootstrap ClassLoader:启动类加载器 负责加载 JAVA_HOME的jre/lib/rt.jar里面所有的class
3. Extension ClassLoader:扩展类加载器
负责加载java平台中扩展功能的一些jar包,包括$JAVA_HOME中除jre/lib/*.jar或者-DJava.ext.dirs=XXX指定路径下的jar包
4. Application ClassLoader:应用类加载器 负责加载classpath中指定的jar和目录中的class

双亲委派模型

JVM工作过程
双亲委派模型来加载类的过程:
5. 当前类加载器会从自己已经加载的类中查询此类是否已经加载,如果已经加载则返回原来已经加载的类。
6. 如果没有找到,就会委派父亲记载其加载,父类加载器采用同样的策略,查看自己已经加载的类是否包含这个类,有则返回,没有的话就委托父类,知道委托给启动类加载器为止。因为启动类加载器的父类为空,到启动类加载器就不会网上进行委托。
7. 如果启动类加载器加载失败,就会使用扩展类加载器进行加载,继续失败则使用应用类加载器来进行加载,继续失败就会抛出一个异常:ClassNotfoundException

双亲委派的优点

  1. 安全性,比卖你用户自己编写的类动态替换java的一些核心类,如果不采用双亲委派模型的加载方式进行类的加载工作,那我们就可以随时使用自定义的类来动态代替java核心API中定义的类。例如:如果黑客将“病毒代码”植入到自定义的String类当中,随后类加载器将自定义的String类加载到JVM上,那么此时就会对JVM产生意想不到“病毒攻击”。而双亲委派的这种加载方式就会避免这种情况,因为String类已经在启动时就被应用类加载器进行加载。
  2. 避免类的重复加载。 JVM判定两个类是否时同一个类,不仅仅根据类名是否相同进行判定,还需要判断加载该类的类加载器是否时同一个类加载器,相同的class文件被不同的类加载器加载得到的结果就是两个不同的类。
上一篇:Android 类加载原理


下一篇:【JVM进阶之路】十四:类加载器和类加载机制