内存区域
程序计数器
概念:当前线程的执行字节码行号指示器。
每条线程都需要一个独立的程序计数器。
java虚拟机中没有规定程序计数器的任何OutOfMemoryError情况的区域。
Java虚拟机栈
每个方法只从的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。
该区域定义两种异常:1.如果线程请求的栈深度大于虚拟机允许深度,将抛出StackOverflowError;2.如果虚拟机栈允许动态扩展,如果扩展时无法申请到固定的内存抛出OutOfMemoryError
本地方法栈
native method:java调用的不是由java实现的方法被称为本地方法
本地方法栈和jvm栈发挥的作用十分相似,区别只是一个为java方法服务,一个为native方法服务。
本地方法栈也会抛出StackOverflowError和OutOfMemroyError异常
Java堆
存放对象实例
所有线程共享一块内存区域
方法区
各个线程共享的内存区域
用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
无法满足内存分配需求时,将抛出OutOfMemroyError异常
运行时常量池
运行时常量池是方法区的一部分,用于存放编译器生成的各种字面量和符号引用。
字面量:即是这个量本身,例如 int a = 5 中5即是字面量。
符号引用:一组符号来表示引用的目标,可以是任何形式的字面量,符号引用与虚拟机的内存布局无关,引用的目标并不一定加载到内存中。
直接引用:1.直接指向目标的指针(比如,指向“类型”【Class对象】、类变量、类方法的直接引用可能是指向方法区的指针);2.相对偏移量(比如,指向实例变量、实例方法的直接引用都是偏移量);3.一个能间接定位到目标的句柄。直接引用是和虚拟机的布局相关的,同一个符号引用在不同的虚拟机实例上翻译出来的直接引用一般不会相同。如果有了直接引用,那引用的目标必定已经被加载入内存中了。
运行期间也可以将常量放入常量池中,比如String的intern()方法。
和方法区一样也会抛出OutOfMemoryError异常。
直接内存
不属于java虚拟机的内存区域
NIO类引入了一种给予通道的缓冲区I/O方式,它可以使用Native函数直接分配堆外聂村,然后通过一个存储在java堆中的DirectByteBuffer对象作为这块内存的引用进行操作。
各个内存区域内存区域总和大于物理内存限制,可能导致动态扩展时出现OutOfMemoryError异常。