一提到Java,我们第一直觉就是Java语言。其实Java不仅仅是一种编程语言,它还是由一系列计算机软件和规范形成的技术体系,这个技术体系提供了完整的用于软件开发和跨平台部署的支持环境,并且广泛应用于嵌入式系统/移动终端/企业服务器/大型机等场合。从广义上讲,类似于JRuby等运行在JVM上的语言及其相关的程序都属于Java技术体系中的一员。但是,一般咱们从传统上理解,sun官方所定义的Java技术体系包括:Java程序设计语言/各个平台上的JVM虚拟机/class文件/Java API类库/还有第三方Java类库。我们把JVM JavaAPI 和Java程序设计语言这三部分称为JDK。
简单介绍了Java之后,就进入今天的主题,jvm内存区域模型。相对于c或者c++来说,Java的自动内存机制可以每次new对象写配对的delete/free代码。不容易出现内存溢出和内存泄漏的情况。同样,有利肯定就有弊处。一旦出现内存泄漏或者内存溢出的情况,排查问题也是一项棘手的工作。
JVM在执行Java程序时,会把Java虚拟机管理的内存划分不同的数据区域。每个区域都有自己的用途。如下图所示:
这张图就表示了Java虚拟机运行时数据区。下面我们就来一一介绍着不同区域的内容。
程序计数器
程序计数器program counter register , 是一块较小的内存空间。我们可以把它当前线程所执行的字节码的行号指示器。
而在虚拟机的概念模型中,字节码解释器,是通过改变这个程序计数器的值,来选去下一条需要执行的字节码指令。一些基础功能,比如分支/循环/跳转/异常处理/线程恢复等,就是得需要这个计数器才能完成。
Java虚拟机中的多线程就是 通过线程轮流切换 并 分配处理器执行时间 的方式来实现。在任何一个时间内,一个处理器也只能执行一个线程中的指令。所以,线程之间是来回切换的,为了线程切换后能恢复到正确的执行位置。所以每条线程都配置了一个专用的独立的 程序计数器。这样,各个线程的程序计数器之间不会相互干扰,独立存储。我们称之为“线程私有”内存。
Java虚拟机栈
Java虚拟机栈 VM stack,就是执行Java方法的内存模型。这个也是线程私有的,生命周期跟线程一致。
每个Java方法被执行的时候,都会创建一个“栈帧” ,用于存储 局部变量表 和 操作数栈 和 动态链接 和局部变量区 等信息
每个Java方法从被调用 到 执行完 这个过程,就对应着一个栈帧在虚拟机栈中 从入栈 到 出栈的过程。
下图是关于一个“栈帧”的示意图:
其中值得注意的是,栈帧中的局部变量表:局部变量区所需要的内存空间,是在编译期间就完成分配的。当进入一个方法是,这个方法需要在帧中分配多大的局部变量空间是完全确定的。方法在运行期间,是不会改变局部变量表的大小。
本地方法栈
本地方法栈 native method stack ,与上面介绍的虚拟机栈基本类似。区别之处在于:上面的虚拟机栈 为执行Java方法的内存模型,而本地方法栈 是为native方法也就是操作系统提高的方法 服务的。有的虚拟机(如sun Hotspot虚拟机),就直接把本地方法栈和Java虚拟机栈合并在一起。
Java堆
原文地址:https://www.cnblogs.com/starstarstar/p/8723456.html