Java内存模型-深入理解JAVA虚拟机-笔记(一)

Java与C++之间有一堵由内存动态分配和垃圾收集技术所围成的“高墙”,墙外的人想进去,墙里的人却想出来。

运行时数据区域

Java虚拟机在执行Java程序的过程中,会把所有它管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途,.根据的规定,java虚拟机所管理的内存将会包括以下几个运行时数据区域,如图所示:
Java内存模型-深入理解JAVA虚拟机-笔记(一)_第1张图片

1. 程序计数器

程序计数器(Program Counter Register)是一块较小的内存空间,它可以看做是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环、跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器来完成。
                                             ------ 《深入理解JAVA虚拟机》

特点:

  • 线程私有
  • JVM规范中唯一没有规定OutOfMemoryError情况的区域
  • 如果正在执行的是Native 方法,则这个计数器值为空
首先,为什么是线程私有?

Java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间的方式来实现,也就是说,在同一时刻一个处理器内核只会执行一条线程,处理器切换线程时并不会记录上一个线程执行到哪个位置,所以为了线程切换后依然能恢复到原位,每条线程都需要有各自独立的程序计数器。

为什么没有规定OutOfMemoryError?

如上文,程序计数器存储的是字节码文件的行号,而这个范围是可知晓的,在一开始分配内存时就可以分配一个绝对不会溢出的内存。

为什么执行Native方法,值为空?

Native方法大多是通过C实现并未编译成需要执行的字节码指令,也就不需要去存储字节码文件的行号了。

2. JAVA虚拟机栈(JVM栈)

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

栈帧

虚拟机栈中的栈元素
用于支持虚拟机进行方法调用和方法执行的数据结构

每个方法从开始调用到执行完成的过程,就对应着一个栈帧从入栈到出栈的过程

在活动线程中,只有位于栈顶的栈帧才是有效的,称为当前栈帧,与这个栈帧相关联的方法称为当前方法,执行引擎运行的所有字节码指令都只针对当前栈帧进行操作。

栈帧主要包括:局部变量表 操作数栈 动态连接 方法返回地址 附加信息

局部变量表

局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的的局部变量。

操作数栈

方法的执行操作在操作数栈中完成,每一个字节码指令往操作数栈进行写入和提取的过程,就是入栈和出栈的过程。

动态链接

每个栈帧都包含一个指向运行时常量池中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程的动态连接。

静态解析:常量池中的符号引用,一部分会在类加载阶段或第一是时间的时候就转化为直接引用。
动态连接:另一部分在每一个运行期间转化为直接引用,这个过程称作动态连接。

3. 本地方法栈

本地方法栈(Native Method Stacks)与 Java 虚拟机栈所发挥的作用是非常相似的,其区别不过是虚拟机栈为虚拟机执行 Java 方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的 Native 方法服务。虚拟机规范中对本地方法栈中的方法使用的语言、使用方式与数据结构并没有强制规定,因此具体的虚拟机可以自由实现它。

4. JAVA堆

Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。

Java堆是垃圾收集器管理的主要区域,因为很多时候也被称作GC堆(Garbagr Collcted Heap,幸好没翻译成垃圾堆)。说到垃圾收回机制,就必须提到垃圾回收机制算法,再展开又是一篇文章了,有兴趣的同学可以看一下,这块也是面试常考的问题。

5. 方法区

JDK7及之前版本的方法区(Method Area)和Java堆一样,是各个线程共享的内存区域,用于存储已经被虚拟机加载的类信息、常量、静态常量、即时编译器编译后的代码等数据。虽然Java虚拟机规范把方法区描述为堆的一个逻辑部分,但它有另外一个名字叫Non-Heap(非堆)。根据Java虚拟机规范的规定,当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。

你可能感兴趣的:(Android)