Java 学习笔记--内存区域(堆和栈的区别)

Author Avatar
ChihoPang 2月 10, 2018
  • 在其它设备中阅读本文章

Java 虚拟机在执行 Java 程序的过程中会把内存划分为若干个不同的数据区域。共分为程序计数器、Java 虚拟机栈、本地方法栈、Java 堆、方法区五种,相关知识点已在表格进行总结。

参考资料

《深入理解 Java 虚拟机》第 2 章

表格总结&原理图

img
img

程序计数器(Program Counter Register)

作用

当前线程所执行的字节码行号指示器。

是否线程私有

线程私有的内存区域。
原因:Java 虚拟机多线程是通过线程轮流切换实现的,所以需要保证线程切换后能恢复正确的执行位置,每条线程都有独立的程序计数器。

内存溢出异常

唯一一个在 Java 虚拟机规范中没有规定任何 OutOfMemoryError 情况的区域。

Java 虚拟机栈(Java Virtual Machine Stacks)

常指的栈内存就是 Java 虚拟机栈,特指局部变量表。

作用

描述 Java 方法执行的内存模型:为每一个方法创建一个栈帧,栈帧内存储局部变量表、操作数栈、动态链接、方法出口等信息,栈帧伴随方法的执行在 Java 虚拟机栈中入栈和出栈。

局部变量表

栈帧中的局部变量表,存储着以下信息:

是否线程私有

线程私有的内存区域。

内存溢出异常

  1. 栈深度超过虚拟机允许深度:StackOverflow Error
  2. 无法申请足够内存:OutOfMemoryError

本地方法栈(Native Method Stack)

HotSopt 等虚拟机已将 虚拟机栈和本地方法栈 合并。

作用

与虚拟机栈类似,虚拟机栈为 Java 方法(字节码)服务,本地方法栈为虚拟机使用到的 Native 方法服务。

是否线程私有

线程私有的内存区域。

内存溢出异常

  1. 栈深度超过虚拟机允许深度:StackOverflow Error
  2. 无法申请足够内存:OutOfMemoryError

Java 堆(Java Heap)

  • 常指的堆内存
  • Java 虚拟机所管理的内存最大的一块
  • 垃圾回收的主要区域
  • 可以处于物理不连续的内存空间,只需逻辑连续

作用

唯一作用:存放对象实例。

是否线程私有

非线程私有,所有线程共享此区域。

内存溢出异常

如果堆中没有内存完成实例分配,且堆无法拓展时,抛出 OutOfMemoryError。

方法区(Method Area)

作用

存放已加载的类信息、常量、静态变量、即时编译后的代码。

是否线程私有

非线程私有,所有线程共享此区域。

内存溢出异常

如果方法区无法满足内存分配需求时,抛出 OutOfMemoryError。

运行时常量池 Runtime Constant Pool

方法区的一部分。用于存放编译期生成的各种字面量和符号引用。