在java运行过程中,java虚拟机会将内存分成几个不同的数据区域,每个数据区域的功能和生命周期都不相同。
1、程序计数器(program counter register)
程序计数器的内存空间较小,字节码解释器通过改变该计数器的值来确定下一条该执行哪条指令,例如循环、跳转、线程等都需要该计数器。
程序计数器是线程独立的,每个线程的计数器之间互不影响,是线程私有的。
此内存区域是java虚拟机中唯一一个没有规定任何情况的区域。
注:OutOfMemoryError–>因为内存溢出或没有可用的内存提供给垃圾回收器时,Java 虚拟机无法分配一个对象,这时抛出该异常
2、虚拟机栈
栈也是线程私有的,每个方法在执行的同时,就会创建一个栈帧,用于存储局部变量、方法等信息,方法执行完毕,出栈。
栈中规定了两种异常:
- *Error异常:是指线程请求的栈深度大于虚拟机所允许的深度。
- OutOfMemoryError异常:是指虚拟机栈动态扩展时,无法申请到足够的内存。
3、堆(GC堆)
堆是java虚拟机内存中最大的区域,是线程共享区域,该区域创建的目的是存放对象实例。
堆是垃圾收集器管理的主要区域。
该区域规定了OutOfMemoryError异常。
4、方法区
方法区是线程共享区域,用于存储已被虚拟机加载的类信息、常量、静态变量等。
该区域规定了OutOfMemoryError异常。
5、运行时常量池
常量池是方法区的一部分,用于存储编译期生成的常量。
该区域规定了OutOfMemoryError异常。
关于虚拟机内存常见的异常OutOfMemoryError:
- java堆溢出:
java.lang.OutOfMeoryError : Java heap space - 虚拟机栈和本地方法栈溢出
这里描述了两种异常
|–线程请求的栈深度大于虚拟机所允许的最大深度,抛出*Error异常
Exception in thread “main” java.lang.*Error
|–虚拟机在扩展栈时无法申请到足够的内存空间,抛出OutOfMemoryError异常。 - 方法区和运行时常量池溢出
java.lang.OutOfMeoryError : PermGen space