JVM运行时数据区域
JVM数据区域分为:程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、运行时常量。
程序计数器
程序计数器是一块较小的内存空间,可以看做是字节码的行号指示器。在JVM多线程程序中,为了程序切换后能恢复到正确的执行位置,每条线程都有一个程序计数器,占用线程独有的内存空间。
Java虚拟机栈
Java虚拟机栈是线程私有的,生命周期与线程相同。
方法被执行的时候,JVM会创建一个栈帧存储局部变量表、操作数栈、动态链接、方法出口等信息。方法的调用和执行完毕分别对应栈帧出栈入栈的过程。
本地方法栈
本地方法栈的作用类似于虚拟机栈,区别在于虚拟机栈为Java方法服务,而本地方法栈为本地(Native)方法服务。
Java堆
Java堆是JVM管理的内存中最大的一块。
堆是所有线程共享的一块内存空间,在虚拟机启动时创建,用于存放对象实例。
方法区
与堆一样,方法区是各个线程共享的内存区域。方法区用于存放已被JVM加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据。如果方法区无法满足新的内存分配需求时,会抛出OutOfMemoryError异常。
运行时常量池
运行时常量池是方法区的一部分。
运行时常量用于存放Class文件的常量池信息表,常量池信息表存放各种字面量和符号引用。
直接内存
直接内存并不是JVM运行时数据区域的一部分,但是也频繁地被使用。
Java的NIO引进了基于通道和缓冲区的IO方式,NIO通过Native函数库直接分配堆外内存,避免了Java堆和Native堆之间频繁切换,以此调高性能。
显然直接内存也会受物理内存的限制,当各个区域的内存总和大于物理内存时会抛出OutOfMemoryError异常。