JVM内存模型详解

作者: 程序员七哥 | 来源:发表于2017-07-03 15:35 被阅读75次

    1、什么是JVM?

    JVM是Java Virtual Machine的缩写,JVM是一种通用于计算机设备的规范,它是一个虚构出来的计算机,是通过在实际计算机上仿真各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。
     JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需要生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。


    Java语言的一个非常重要的特点就是平台无关性。而使用Java虚拟机是实现这一特性的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需要生成Java虚拟机上运行的目标代码(字节码),就可以在多种不同的平台上不加修改的运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java能够“一次编译,到处运行”的原因。

    2、JRE、JDK、JVM是什么关系?

    JRE(JavaRuntimeEnvironment,Java运行环境),也就是Java平台。所有的Java程序都要在JRE下才能运行。一般用户只需要运行已经开发好的Java程序,安装JRE即可。
    JDK(Java Development Kit)是程序开发者用来编译、调式Java程序所用的开发工具包。JDK的工具包也是Java程序,也需要JRE才能运行。为了保持JDK的独立性和完整性,在JDK的安装过程中,JRE也是安装的一部分。所以,在JDK的安装目录下有一个名为jre的目录,用于存放JRE文件。
     JVM(JavaVirtualMachine,Java虚拟机)是JRE的一部分。它是一个虚拟出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。JVM有自己完善的硬件架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。Java语言最重要的特点就是跨平台运行。使用JVM就是为了支持与操作系统的五官,实现跨平台。

    3、JVM原理


    Java编译器只要面向JVM,生成JVM能理解的代码或字节码文件。Java源文件经编译生成字节码程序,通过JVM将每一条指令翻译成不同平台的机器码,然后在在特定平台运行。


    4、JVM的体系结构

    1. Java栈内存,它等价于C语言中的栈,栈的内存地址是不连续的,每个线程都拥有自己的栈。栈里面存储着的是栈帧。
      栈帧包含三类信息:局部变量,执行环境,操作数栈。局部变量用来存储一个类的方法中所用到的变量(方法中的基本数据类型其变量名和值都存储在栈帧中,引用类型变量其变量名存储在栈帧中,对象值存储在堆中)。执行环境用于保存解析器对于Java字节码进行解释过程中需要的信息,包括:上次调用的方法,局部变量指针和操作数栈的栈顶和栈底指针。操作数栈用于存储运行所需要的操作数和结果。栈帧在方法被调用时创建,方法执行结束后销毁。

    2. Java堆是用来存放对象信息的,和栈不同,栈代表一种运行时的状态。换句话说,栈是运行时单位,解决程序该如何执行的问题,而堆是存储的单位,解决数据存储的问题。堆是伴随着JVM的启动而创建的,负责存储所有对象实例和数组的。堆的存储空间和栈一样是不需要连续的。

    3. 程序计数寄存器,程序计数器(Program Counter Register)是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个 计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
      </br>
       由于Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(对于多核处理器来说是一个内核)只会执行一条线程中的指令.因此,为了线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间的计数器互不影响,独立存储,我们称这类内存区域为“线程私有”的内存。如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值则为空(Undefined)。此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError 情况的区域。

    4. 方法区,在Sun JDK中这块区域对应的为PermanentGeneration,又称为持久代。方法区存放了所加载的类的信息(名称、修饰符等)、类中的静态变量、类中定义为final类型的常亮、类中的Field信息、类中的方法信息,当开发人员在程序中通过Class对象的getName、isInterface等方法来获取信息时,这些数据都来源于方法区,同时方法区也是全局共享的,在一定条件下它也会被GC,当方法区需要使用的内存超过其允许的大小时,会抛出OutOfMemory的错误信息。

    5. 运行时常量池(Runtime Constant Pool),存放的为类中的固定的常量信息、方法和Field的引用信息等,其空间从方法区域中分配(常量池之前是放在方法区里面的,也就是在永久代里面的,从JDK7开始移到了堆里面)。

    6. 本地方法栈,JVM采用本地方法堆栈来支持native方法的执行,此区域用于存储每个native方法调用的状态。

    相关文章

      网友评论

        本文标题:JVM内存模型详解

        本文链接:https://www.haomeiwen.com/subject/ugyacxtx.html