Java 虚拟机( Java Virtual Machine,缩写为 JVM ):是一种能够运行 Java 程序的抽象计算机。
特点:实现 Java 平台无关性,使得编译后的 Java 程序指令并不直接在硬件系统的 CPU 上执行,而由 JVM 执行。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 Java 虚拟机上运行的目标代码(字节码),再由 JVM把字节码解释成具体平台上的机器指令执行,就可以在多种平台上不加修改地运行。
Java 虚拟机运行时数据区
Java 虚拟机在执行 Java 程序的过程中会把它所管理的内存划分为若干个不同的数据区域,以下是 Java 虚拟机所管理的运行时数据区:
程序计数器
和 pc 寄存器来存放下一条指令地址类似,JVM 的程序计数器可看作当前线程所正在执行(不是下一条)的字节码的行号指示器。在虚拟机的概念模型里,字节码解释器工作时可以通过改变这个计数器的值来选取下一条需要执行的字节码指令。
Java 虚拟机的多线程是通过线程轮流切换并分配处理器执行的时间来实现的,在任何确定的某个时刻,一个处理器都只会执行一条线程中的指令。因此,为了线程切换后能恢复到正确的执行位置,每条线程都有一个独立的程序计数器,即线程私有。
Java 虚拟机栈
描述了 Java 方法 执行的内存模型,即存放每个方法执行时创建的栈帧,用于存放局部变量表、操作数栈、动态链接、返回地址等信息,线程私有。
本地方法栈
类似于 Java 虚拟机栈执行 Java 方法服务,本地方法栈则为虚拟机使用到的 Native 方法服务,线程私有。
Java 堆
存放分配的对象实例及数组,可以处于物理上不连续的内存空间,只要逻辑连续即可,线程共享,区域主要由垃圾收集器管理。
方法区
存储一个类的结构信息,例如运行时常量池、成员变量和方法数据等,线程共享。
注意:方法区≠永久代(Permanent Generation),仅仅是因为HotSpot虚拟机中使用永久代来实现方法区,以此像管理堆内存一样来管理方法区而已。
运行时常量池
方法区的一部分,用于存放编译期间生成的各种字面量(文字所表示的取值,即固定值,对于 String 而言,形如 String str="hello"
这种属于字面量,有专门的字符串池进行保存,形如String str = new String("hello")
这种不属于字面量,则是在堆上分配)和符号引用(相当于Linux中一个文件的软链接,在该类实际执行时,才把符号引用转为直接引用)。
对象的分配、布局和访问
在HotSpot虚拟机上,Java 堆中对象的分配、布局和访问的过程,