Java虚拟机内存模型-运行时数据区域划分

154 阅读3分钟

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的高墙,墙外面的人想进去,墙里面的人却想出来。 -《深入理解java虚拟机》

对于墙外边的Java而言,Java虚拟机内存模型的划分,如果依据线程是否可以共享,基本可以分为两大类:其一、线程共享区域,其二、线程非共享区域。即,方法区、虚拟机栈、本地方法栈、程序计数器、Java堆,其中在方法区中还有一个常量区。如下图:

引用杨俊明老师分享(图1)

下面对各个区域做简要描述:

1、程序计数器(Program counter register)

是一块较小的内存空间,属于非线程共享,”线程私有“内存,它的作用可以看做是当前线程所执行的字节码的行号指示器。

字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。

2、java虚拟机栈

Java虚拟机栈(Java Virtual Machine Stacks)也是线程私有的,它的生命周期与线程相同。虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接、方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

3、本地方法栈

本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,属于”线程私有“,其区别不过是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的Native方法服务。

4、堆(java heap)

对于大多数应用来说,Java堆(Java Heap)是Java虚拟机所管理的内存中最大的一块。Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

堆的话也是GC回收主要关注的内存区域,这里就不展开了。

5、方法区(method area)

方法区中主要存放类解构、类成员定义、static静态成员等,属于线程共享,其中在方法区中还有划分出一部分叫做运行时常量池(runtime constant pool),比如:字符串,int -128~127范围的值。

对于java内存模型或者说java虚拟机运行时候内存区域划分,做了大致的概念上的介绍。分类主要是依据线程是否可共享来划分。“线程私有”:程序计数器、虚拟机栈,本地方法栈;“线程共享”:java堆、方法区(包含运行时常量池)。