jvm运行时数据区域
java虚拟机在执行java程序的过程中将它所管理的内存划分为以下几个运行时数据区域:
程序计数器(Program Counter Register)
虚拟机栈(VM Stack)
本地方法栈(Native Method Stack)
堆(Heap)
方法区(Method Area)
线程私有区域(程序计数器、虚拟机栈、本地方法栈),线程共享区域(堆、方法区),直接内存。线程私有数据区域生命周期与线程相同, 依赖用户线程的启动/结束 而 创建/销毁(在 Hotspot VM 内)。线程共享区域随虚拟机的启动/关闭而创建/销毁。直接内存并不是 JVM 运行时数据区的一部分。
1. 程序计数器
程序计数器是当前线程执行的字节码的行号指示器,为了线程切换后能够恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,个线程之间的程序计数器互不影响,各自独立存储。这类内存区域为“线程私有”的区域。此内存区域是唯一一个没有OutOfMemoryError的区域。
2. 虚拟机栈虚拟机栈描述的是Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。栈容量只由-Xss参数设定
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverFlowError
如果虚拟机在扩展时无法申请到足够的内存空间,则抛出OutOfMemoryError异常
/** * VM Args: -Xss160k * -Xss的最小值为160k **/ public class JavaVMStackSOF { private int stackLength = 1; public void stackLeak(){ stackLength++; stackLeak(); } public static void main(String[] args) throws Throwable { JavaVMStackSOF oom = new JavaVMStackSOF(); try { oom.stackLeak(); } catch (Throwable e){ System.out.println("stack length : " + oom.stackLength); throw e; } } }