java虚拟机,可以把它理解为跑在操作系统之上的虚拟机,它是实现java平台无关的重要机制(因为编译后的java程序:class文件是在jvm中执行的),所以要运行java程序必须先要安装jvm。
常用jvm实现:
既然jvm作为虚拟机,很显然它被作为一台机器使用,根据冯诺依曼计算机架构,就会分处理器、内存、IO等,因为java程序是自动分配内存和回收内存的,所以这里我
们重点讨论jvm自动内存管理机制:
1、jvm运行时数据划分
(1)程序计数器(Program Counter Register)
存放线程执行指令,线程独享,不会内存溢出。
在JVM规范中规定,如果线程执行的是非native方法,则程序计数器 中保存的是当前需要执行的指令的地址;如果线程执行的是native方法,则程序计数器中的值是undefined。
由于程序计数 器中存储的数据所占空间的大小不会随程序的执行而发生改变,因此,对于程序计数器是不会发生内存溢出现象(OutOfMemory)的
(2)java虚拟机栈(VM Stack)
java方法执行内存模型,线程独享,Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。
(3)本地方法栈(Native Method Stack)
本地方法栈与Java栈的作用和原理非常相似。区别只不过是Java栈是为执行Java方法服务的,而本地方法栈则是为执行本地方法(Native Method)服务的。在JVM规范中,并没有对本地方发展的具体实现方法以及数据结构作强制规定,虚拟机可以自由实现它。在HotSopt虚拟机中直接 就把本地方法栈和Java栈合二为一。
(4)堆(Heap)
存放对象,线程共享,垃圾回收的主要区域
(5)方法区
(Method Area)
线程共享的区域,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。在JVM规范中,没有强制要求方法区必须实现垃圾回收。很多人习惯将方法区称为“永久代”,是因为HotSpot虚拟机以永久代来实现方法区,从而JVM 的垃圾收集器可以像管理堆区一样管理这部分区域,从而不需要专门为这部分设计垃圾回收机制。不过自从JDK7之后,Hotspot虚拟机便将运行时常量池 从永久代移除了。
思考问题:
1、jvm为什么要这样定义运行时内存?
2、各个区域在运行时的具体作用和使用时机?
3、如果让你设计你会怎么做?