一、堆
-
定义
- 存储对象实例的内存区域
-
特点
- JVM中最大的一块内存
- 所有线程共享的
- 垃圾回收的主要区域
-
存储
-
对象
-
数组
-
字符串常量池
- 从Java7开始,字符串常量池从方法区移至堆中。它存储的是string对象的直接引用,而不是直接存放的对象。
-
静态变量
- 原本存放于方法区,但从JDK7开始被迁移到堆中
-
线程分配缓冲区TLAB(Thread Local Allocation Buffer)
- TLAB是虚拟机在堆内存的eden划分出来的一块专用空间,是线程专属的。在线程初始化时,虚拟机会为每个线程分配一块TLAB空间,只给当前线程使用,如果需要分配内存,就在自己的空间上分配,这样就不存在竞争的情况,可以大大提升分配效率。
- 只是在“分配”这个动作上是线程独享的,至于在读取、垃圾回收等动作上都是线程共享的
-
二、虚拟机栈
-
定义
- 方法执行的内存模型
-
特点
- 不需要进行 GC
- 线程私有的
- 方法执行时入栈,方法执行完出栈
-
存储
-
栈帧(一个方法一个栈帧(FILO))
组成
-
局部变量表
- 存放局部变量的内存区域
-
操作数栈
- 存放操作常量的内存区域
-
动态链接
- 将常量池中的符号引用在运行期转化为直接引用
-
方法出口
- 存放方法执行完位置的内存区域
-
-
三、方法区(规范)
-
java7(含)以前
- 实现:永久代
- 堆内部,非堆,跟年轻代和老年代是一块连续的物理内存
- 类信息、静态变量、常量、JIT 编译后的代码、运行时常量池、字符串常量池
-
java8
-
实现:元空间(本地内存)
- 避免OOM异常
- 永久代的 GC 特别难搞,严重影响 Full GC 的性能
-
存储
-
类的元数据
- 包、类、方法、字段、的描述信息
-
静态常量池
-
定义
- 也被称为class文件常量池,主要存放编译期生成的各种字面量和符号引用
-
组成
-
字面量
- 文本字符串、final修饰的常量等
-
符号引用
- 以一组符号来描述所引用的目标
- 直接指向内存中某一地址的引用称为直接引用
- 在类被加载解析阶段会被转化成直接引用
-
-
-
运行时常量池
-
定义
- 当类被加载到内存中后,JVM会将class常量池中的内容存放到运行时常量池中,与class常量池是一一对应
-
存储
- 存储的主要是编译期间生成的字面量、符号引用等等
-
作用
- 在运行期间将符号引用解析为直接引用
-
-
-
四、本地方法栈
-
与虚拟机栈作用类似
-
native 方法
-
存在的意义
- 有时java应用需要与java外面的环境交互,比如底层操作系统,用C/C++语言
-
不需要进行 GC
五、程序计数器
-
记录下一个字节码执行的地址
-
线程的位置
-
每个线程独立拥有一个
- 保证每个线程切换都能互不干扰
-
生命周期与线程一致
-
不会OOM
-
不需要进行 GC