JVM内存结构
程序技术器
介绍:
- 是一块
很小
的内存空间
,可以看作当前线程的所执行的字节码
的行号指数器
,字节码解释器需要通过改变这个计数器
的值来选取下一条需要执行的字节码指令
。 - 分支、循环、跳转、异常处理、
线程恢复
等操作都依赖程序技术器。 - 每个
线程
都拥有独立的程序计数器。 - 如果正在执行的是
本地方法(native)
,那么计数器的值为空
特点:线程私有
,唯一不存在内存溢出的区域
java虚拟机栈
介绍:
- 虚拟机栈描述的是
java线程的内存模型
- 线程中每个方法执行的时候都会创建
栈帧
用于存储局部变量表
、操作数栈
、动态连接
、方法出口
等信息。 - 每个方法被调用到执行完,对应着
栈帧
在虚拟机中从入栈
到出栈
的过程
特点:线程私有
、线程请求的栈深度超过虚拟机运行的深度,将会抛出StackOverflowError异常
本地方法栈
介绍:
- Hot-Spot虚拟机直接将
本地方法栈
和虚拟机栈
合二为一。
特点:线程私有
,在栈深度扩展失败时也会抛出StackOverflowError
异常
java堆
介绍:
- 《java虚拟机规范中》堆描述:
所有的对象实例以及数组都应当在堆上分配
- java堆是
垃圾收集管理
的内存区域,也可以称作GC堆
- 堆可以处于
物理上不连续的内存空间中
,但在逻辑上应该被视为连续的,但是对于大对象
、数组
,很可能会要求连续的内存空间
特点:线程共享
,堆内存不够时会抛出OutOfMemoryError
异常
方法区
介绍:
- 储存
已被虚拟机加载的类型信息
、常量
、静态变量
、即时编译器编译后的代码缓存
- jdk8以前Hot-Spot方法区的实现称为
永久代
,是堆内存
的一部分 - jdk9以后Hot-Spoy方法区的实现称为
元空间
,使用的是直接内存
特点:线程共享
、无法满足新的分配需求时会抛出OutOfMemoryError
异常
运行时常量池
介绍:
- 是
方法区的一部分
,Class文件中除了有类的版本
、字段
、方法
、接口
等描述信息外,还有一个是常量池表
,用于存放编译器生成的各种字面量
和符号引用
,这部分内容会在类加载后
放入运行时常量池
- 一般会把
符号引用
翻译成直接引用
再放入运行时常量池
- 运行时常量池具有
动态性
,并非只有编译期间才能产生常量
,运行时也可以将常量
放入池中,比如String的intern()
方法
特点:无法申请内存时抛出OutOfMemoryError
异常
直接内存
直接内存并不是虚拟机运行时的内存区域
介绍:
- jdk1.4后引入了
NIO
,可以操作直接内存
,在IO操作时可以显著提升性能
特点:IO操作时提升性能
,收到机器物理内存的限制,无法动态扩展时抛出OutofMemoryError
异常