程序计数器(Program Counter Register)
当前线程执行的行号指示器,记录的是正在执行的虚拟机字节码指令的地址 线程私有,每个线程都有独立的程序计数器 线程切换的重要工具 唯一没有oom的区域
java虚拟机栈(Java Virtual Machine Stack)
-
线程私有
-
java方法执行的线程内存模型,每个方法执行时,都会创建一个栈帧,每个栈帧中记录局部变量,方法出口,动态连接,操作数栈,每个方法被调用直至执行完毕的过程,就是一个栈帧从虚拟机栈中入栈到出栈的过程。所以也叫做方法栈。
-
局部变量表:存放编译期的各种基本数据类型(八大基础出局类型)、对象引用(不是对象本身,只是一个引用)和returnAddress类型。
-
会有StackOverflowError和OutOfMemoryError异常
本地方法栈(Native Method Stacks)
- 和虚拟机栈类似,虚拟机栈记录的是虚拟机执行java方法,本地方法栈则是为虚拟机执行本地方法服务。
java堆(java heap)
-
虚拟机管理内存最大的一块
-
线程共享,随虚拟机启动时创建
-
保存实例对象和数组
-
GC发生的区域
-
支持拓展 -Xms,-Xmx
-
堆中没有内存完成实例分配,并且堆内存无法拓展时,会出现OOM异常
-
基于经典分代设计:年轻代(Eden区,S0,S1),老年代
方法区(Method Area)
-
线程共享,别名非堆(non-heap),目的是与java堆区分开来
-
存储已被虚拟机加载的类型信息,常量,静态变量,即时编译器编译后的代码缓存等数据
-
基于永久代实现方法区
-
-XX: MaxPermSize设置永久代大小
-
1.8开始废弃永久代概念,使用本地内存实现的元空间代替
-
有垃圾回收,但效率不高,条件苛刻
-
有OOM异常
运行时常量池(Runtime Constant Pool)
-
方法区的一部分,用于存放编译器生成的各种字面量和符号引用。
-
可以动态添加,如String.intern()
-
会OOM
直接内存(Direct Memory)
-
不是虚拟机运行时数据区的一部分
-
NIO,可以使用native函数库直接分配堆外内存,然后通过DirectByteBuffer对象作为这块内存的引用进行操作。显著提高了性能,避免了java堆和Native对中来回复制数据
-
也会有OOM