文章目录
运行时数据区的组成概述
JVM的运行时数据区,不同虚拟机实现可能略微有所不同,但都会遵从Java虚拟机规范,Java8虚拟机规范中规定,Java虚拟机所管理的内容将会包括以下几个运行时数据区域:
-
程序计数器(Program Counter Register)
程序计数器是一块较小的内存空间,可以把它看作是当前线程所执行的字节码的行号指示器。 -
Java虚拟机栈(Java Virtual Machine)
描述的是Java方法执行的内存模式,每个方法在执行的同时都会创建一个线帧(Stack Frame)用于存储局部变量表,操作数栈,动态链接,方法出口等信息,每个方法从调用直至执行完成的过程,都对应着一个线帧在虚拟机栈中入栈到出栈的过程。 -
本地方法栈(Native Method Atack)
与虚拟机栈的作用一样,只不过虚拟机栈是服务于Java方法的,而本地方法栈是为虚拟机调用Native(本地)方法服务的。 -
Java堆(Java Heap)
是Java虚拟机中内存最大的一块,是被所有线程所共享的,在虚拟机启动的时候就创建好了,Java堆唯一的目的就是存放对象的实例,几乎所有的对象实例都是在这里分配内存的。 -
方法区(Method Area)(也叫元空间)
方法区就是用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译后的代码等数。
方法区是很重要的系统资源,是硬盘和CPU的中间桥梁,承载着操作系统和应用程序的实时运行。
JVM内存布局规定了Java在运行的过程中内存申请,分配,管理的策略,保证了JVM的高效稳定的运行,不同的JVM在对于内存的规划方式和管理机制存在着部分的差异。
我们现在以使用最为流行的HotSpot虚拟机为例讲解。
Java虚拟机定义了序列行期间会使用到运行数据区,其中有一些会随着虚拟机启动而创建,随着虚拟机退出而销毁。另外一些则是随着线程一一对应。这些与线程对应的区域会随着线程开始和结束而创建销毁的。
堆,方法区(元空间) 是主要用来存放数据的,是线程共享的
程序计数器,本地方法栈,虚拟机栈属于运行程序的,是线程私有的
程序计数器(Program Counter Register)
概念
JVM中的程序计数寄存器(Program Counter Register)中的Register命名源自于CPU的寄存器,寄存器存储指令相关的现场信息。CPU只有把数据装载放在计数器上才能运行。
这里的程序计数器并不是物理意义上所用CPU上的寄存器,可以将它翻译为PC寄存器(指令寄存器)会更加的合适(也称为程序钩子),并且不容易引起一些不必要的误会。JVM中的PC寄存器是对物理PC寄存器的一种抽象模拟。
计数器是线程私有的
由于JVM的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现的,所以在任何一个确定的时刻,一个处理器都只会执行一条线程中的指令。因此未来线程切换后能恢复到正确的执行位置,每条线程都需要有一个独立的程序计数器,各条线程之间计数器互不影响,独立存储,我们成这类内存区域为 “线程私有” 的内存。
作用
● 程序计数器的作用主要就是用来存储下一条指令的地址,也就是将要执行的指令代码,由执行引擎来读取下一条的指令。
● 它是一块很小的内存空间,几乎是可以忽略不计的,它也是运行速度最快的存储区域。
● 在JVM的规范当中,每个线程都有它自己的程序计数器,属于线程私有的,所以它的生命周期是和线程的生命周期保持一致的。
● 在任何时间里面里面一个线程都只能有一个方法来执行,也就是所谓的当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址。
● 程序计数器是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
● 字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
● 程序计数器也是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域,就是唯一一个不会出现内存溢出的区域。
以单核CPU为例,计算机在运行的时候并不是将一个线程做完,再去干下一个线程。而是通过时间的控制,在各个线程之间来回运行,也就是实现线程上宏观的并行。那么在线程之间转换的时候,就通过PC寄存器记录线程中当前栈帧运行到第几行。以方便下次轮到这个线程的时候,接着向下运行。
寄存器记录当前线程做执行的位置。
Java虚拟机栈(Java Virtual Machine)
虚拟机栈出现的背景
由于Java只一种跨平台的设计,所以Java的指令都是根据栈来设计的。因为不同平台的CPU机构不同,所以是以面向对象的设计思想是不能基于寄存器来设计的。
基于栈的指令设计的优点就是跨平台,指令集少,编译器容易实现,缺点是性能下降,实现同样功能就需要更多的指令集才能实现。
栈和堆的区别
栈是运行时的单位,堆是存储时的单位
就可以理解为:
栈:就是解决程序的运行问题,就是程序如何的去执行,或者说如何的处理数据。也是由操作系统来代替我们进行分配。(加载方法运行的)
堆:就使解决的数据的存储问题。就是数据处理前或者处理后,应该把数据放在那个地方。就是由程序员来对其进行管理。(存储对象的)
什么是Java虚拟机栈
Java虚拟机栈(Java Virtual Machine Stack)ÿ