JVM—工作原理

在网上找到一个讲JVM的ppt,觉得讲的非常好,将重点整理下来。详细的ppt在我的下载空间中

http://download.csdn.NET/detail/u011936381/6959809

 

JVM的生命周期

一、首先分析两个概念

JVM实例和JVM执行引擎实例
(1)JVM实例对应了一个独立运行的Java程序
         它是进程级别
(2)JVM执行引擎实例则对应了属于用户运行程序的线程
          它是线程级别的

二、JVM的生命周期
    (1)JVM实例的诞生
            当启动一个Java程序时,一个JVM实例就产生了,任何一个拥有public static void main(String[] args)函数的class都可以作为JVM实例运行的起点

    (2)JVM实例的运行
         main()作为该程序初始线程的起点,任何其他线程均由该线程启动。JVM内部有两种线程:守护线程和非守护线程,main()属于非守护线程,守护线程通常由JVM自己使用,java程序也可以标明自己创建的线程是守护线程。
    
    (3)JVM实例的消亡
      当程序中的所有非守护线程都终止时,JVM才退出;若安全管理器允许,程 序也可以使用Runtime类或者System.exit()来退出。

 

JVM的体系结构

《JVM—工作原理》

JVM的内部体系结构分为三部分,
(1)类装载器(ClassLoader)子系统
       作用: 用来装载.class文件
(2)执行引擎
       作用:执行字节码,或者执行本地方法 
(3)运行时数据区
       方法区,堆,java栈,PC寄存器,本地方法栈

 

JVM将整个类加载过程划分为了三个步骤:
(1)装载
      装载过程负责找到二进制字节码并加载至JVM中,JVM通过类名、类所在的包名通过ClassLoader来完成类的加载,同样,也采用以上三个元素来标识一个被加载了的类:类名+包名+ClassLoader实例ID。
(2)链接
      链接过程负责对二进制字节码的格式进行校验、初始化装载类中的静态变量以及解析类中调用的接口、类。
      在完成了校验后,JVM初始化类中的静态变量,并将其值赋为默认值。
      最后一步为对类中的所有属性、方法进行验证,以确保其需要调用的属性、方法存在,以及具备应的权限(例如public、private域权限等),会造成NoSuchMethodError、NoSuchFieldError等错误信息。
(3)初始化
      初始化过程即为执行类中的静态初始化代码、构造器代码以及静态属性的初始化,在四种情况下初始化过程会被触发执行:
      调用了new;反射调用了类中的方法;子类调用了初始化;JVM启动过程中指定的初始化类。

执行引擎

JVM通过执行引擎来完成字节码的执行,在执行过程中JVM采用的是自己的一套指令系统,每个线程在创建后,都会产生一个程序计数器(pc)和栈(Stack),其中程序计数器中存放了下一条将要执行的指令,Stack中存放Stack Frame,表示的为当前正在执行的方法,每个方法的执行都会产生Stack Frame,Stack Frame中存放了传递给方法的参数、方法内的局部变量以及操作数栈,操作数栈用于存放指令运算的中间结果,指令负责从操作数栈中弹出参与运算的操作数,指令执行完毕后再将计算结果压回到操作数栈,当方法执行完毕后则从Stack中弹出,继续其他方法的执行。

运行时数据区

JVM在运行时将数据划分为了6个区域来存储,而不仅仅是大家熟知的Heap区域,这6个区域图示如下:

《JVM—工作原理》

第一块: PC寄存器
      PC寄存器是用于存储每个线程下一步将执行的JVM指令,如该方法为native的,则PC寄存器中不存储任何信息。
第二块:JVM栈
      JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean、char、byte、short、int、long、float、double)、部分的返回结果以及Stack Frame、函数的参数值,非基本类型的对象在JVM栈上仅存放一个指向堆上的地址
第三块:堆(Heap)
       Heap是大家最为熟悉的区域,它是JVM用来存储对象实例以及数组值的区域,可以认为Java中所有通过new创建的对象的内存都在此分配,Heap中的对象的内存需要等待GC进行回收。

第四块:方法区域(Method Area)
       (1)方法区域存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常量、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象中的getName、isInterface等方法来获取信息时,这些数据都来源于方法区域,可见方法区域的重要性,同样,方法区域也是全局共享的,在一定的条件下它也会被GC;当方法区域需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。
       (2)在Sun JDK中这块区域对应的为Permanet Generation,又称为持久代,默认为64M,可通过-XX:PermSize以及-XX:MaxPermSize来指定其大小。
第五块:运行时常量池(Runtime Constant Pool)
       类似C中的符号表,存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配。
第六块:本地方法堆栈(Native Method Stacks)
       JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。 

    原文作者:天涯海角路
    原文地址: https://www.cnblogs.com/aademeng/articles/6188182.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞