JVM内存管理机制

1.要学习Java虚拟机的内存管理机制首先要学习Java虚拟机的数据区分布,如下图所示

                                          JVM内存管理机制

JVM运行时数据区分为两个大的区域,分别为线程独占区和线程共享区。线程我们都知道,是轻量进程,是顺序执行单元,是程序执行流的最小单元。而线程独占区就是每一个线程所拥有的数据区域,线程共享区则是多个线程共用的一块数据区域。线程独占区域包括虚拟机栈、本地方法栈和程序计数器;线程共享数据区包括方法区和堆。接下来详细地学习每一部分的结构和功能。

2.程序计数器

程序计数器处于线程独占区,是一块很小的内存空间,可以看作是当前线程所执行的字节码的行号指示器。

由于开发者无法直接操作程序计数器这一区域所以此块区域为Java虚拟机规范中唯一一块没有规定内存溢出错误(OutOfMemoryError)的区域。

3.虚拟机栈

Java虚拟机栈描述的是Java方法执行的动态内存模型。

每个方法执行都会创建一个栈帧,伴随着方法从创建到执行完成。用于存储局部变量表,操作数栈,动态连接和方法出口等。当方法调用结束时栈帧也会被销毁删除。

局部变量表存放编译期可知的各种基本数据类型,引出类型,returnAddress类型。其内存空间在编译期完成分配。当进入一个方法时,这个方法需要在帧分配多少内存是固定的(因为局部变量表中存放的是变量的引用),在方法运行期间不会改变局部变量表的大小。

注:如果在线程中不断地调用方法而不销毁例如递归就容易出现栈满无法申请栈空间的栈溢出错误(*Error)。

       如果为栈扩大空间导致没有内存可以申请占用则会导致内存溢出错误(OutOfMemoryError)。

4.本地方法栈

与虚拟机栈类似,唯一不同就是虚拟机栈为执行Java方法服务而本地方法栈是对执行native方法服务。

5.

Java堆用来存放Java对象实例,一般来说是Java虚拟机所管理的最大一块区域,也是垃圾回收区所管理的重要区域(回收效率高)。

过多占用堆内存,无法申请内存空间时也会抛出内存溢出错误(OutOfMemoryError)。

6.方法区

方法区用于存放虚拟机加载的类信息(类的版本、字段、方法、接口),常量,静态变量,即时编译器编译后的代码的等数据。

申请方法区异常时也会抛出内存溢出错误。