一类是每个线程所独享的:
1)PC Register:也称为程序计数器, 记录每个线程当前执行的指令信。eg:当前执行到哪一条指令,下一条该取哪条指令。
2)JVM Stack:也称为虚拟机栈,记录每个栈帧(Frame)中的局部变量、方法返回地址等。
3)Native Method Stack:本地(原生)方法栈,顾名思义就是调用操作系统原生本地方法时,所需要的内存区域。
上述 3 类区域,生命周期与 Thread 相同,即:线程创建时,相应的区域分配内存,线程销毁时,释放相应内存。
另一类是所有线程共享的:
1)Heap:鼎鼎大名的堆内存区,也是 GC 垃圾回收的主站场,用于存放类的实例对象及 Arrays 实例等。
2)Method Area:方法区,主要存放类结构、类成员定义,static 静态成员等。
3)Runtime Constant Pool:运行时常量池,比如:字符串,int -128~127 范围的值等,它是 Method Area 中的一部分。
Heap、Method Area 都是在虚拟机启动时创建,虚拟机退出时释放。
注:Method Area 区,虚拟机规范只是说必须要有,但是具体怎么实现(比如:是否需要垃圾回收? ),交给具体的 JVM 实现去决定,逻辑上讲,视为 Heap 区的一部分。
上述 6 个区域,除了 PC Register 区不会抛出 StackOverflowError 或 OutOfMemoryError ,其它 5 个区域,当请求分配的内存不足时,均会抛出 OutOfMemoryError(即:OOM),其中 thread 独立的 JVM Stack 区及 Native Method Stack 区还会抛出 StackOverflowError。
最后,还有一类不受 JVM 虚拟机管控的内存区,这里也提一下,即:堆外内存。
可以通过 Unsafe 和 NIO 包下的 DirectByteBuffer 来操作堆外内存。如上图,虽然堆外内存不受 JVM 管控,但是堆内存中会持有对它的引用,以便进行 GC。
原文:https://www.cnblogs.com/freecodewriter/p/14772465.html