JAVA JVM的内存区域划分
线程独有:
1.程序计数器:
记录当前线程执行的字节码行号,不会出现 OOM(OutOfMemoryError)
不会出现 OOM 的核心原因:其内存占用固定且极小,仅用于存储字节码行号,不涉及动态内存分配,也不会累积数据。
2.栈
- 作用:每个线程拥有独立的栈,存储方法调用的局部变量、操作数栈和返回地址。
- 栈深度过大可能导致StackOverflowError。
栈 分为:
(1)虚拟机栈:每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一个方法被调用直至执行完毕的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
(2)本地方法栈:为本地方法(native关键字修饰的方法,如 C/C++ 实现的方法提供内存空间)
本地方法栈(Native Method Stacks)与虚拟机栈所发挥的作用是非常相似的,其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码)服务,而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。
线程共享:
1.方法区 存储类信息、常量池、静态变量等,Java 8 后被 Metaspace 替代
2.堆:是 JVM 管理的最大内存区域,此内存区域的唯一目的就是存放对象实例,Java世界里“几乎”所有的对象实例都在这里分配内存
总结
JVM 内存区域的划分可概括为:
- 线程私有:程序计数器、虚拟机栈、本地方法栈。
- 线程共享:堆、方法区(含运行时常量池)。
- 堆外内存:直接内存。