JVM内存区域与内存溢出异常
1、运行时数据区域
1.1、程序计数器
- 一块较小的内存,它可以看作是当前线程所执行的字节码的行号指示器。
- 线程独有
- 唯一一个没有规定OutOfMemoryError情况的区域
1.2、Java虚拟机栈
- 线程私有,生命周期与线程相同
- 每个方法被执行的时候都会创建一个栈帧,方法的开始到结束对应了栈帧的入栈到出栈
- 这个内存区域定义了两个异常:
- 如果线程请求的栈深度大于虚拟机允许的栈深度,就会报StackOverFlowError
- 如果栈扩展时无法申请到足够的内存,就会报OutOfMemoryError
1.3、本地方法栈
本地方法栈与虚拟机栈的区别是,虚拟机栈为虚拟机执行Java方法服务,而本地方法栈是为本地Native方法服务。
该区域和虚拟机栈一样也会报两种异常,同上。
1.4、Java堆
- 内存中最大一块区域
- 线程共享,在虚拟机启动时创建,用来存放对象实例
- 如果堆中没有内存完成实例分配,并且堆无法扩展时,也会抛出OutOfMemoryError (可以通过通过参数-Xmx和-Xms设定)
1.5、方法区
- 线程共享
- 存储已被虚拟机加载的类型信息、常量、静态变量、即时编译器编译后的代码缓存等数据
- 运行时常量池是方法区的一部分,Class文件中除了有类的版本、字段、方法、接口等描述信息,还有一项信息是常量池表,用于存放编译期生成的各种字面量与符号引用,这部分内容将存放在运行时常量池中。
- 如果方法区无法满足新的内存分配需求时,将抛出OutOfMemoryError异常。