OutOfMemoryError和StackOverflowError
Posted boboshenqi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OutOfMemoryError和StackOverflowError相关的知识,希望对你有一定的参考价值。
内存区域划分
1.程序计数器:当前线程的正在执行的字节码指示器
2.虚拟机栈和本地方法栈:虚拟机栈存储局部变量表(包括方法入参和布局变量)、操作数栈、方法返回地址(调用者的栈帧,包括return返回和异常返回)等
3.堆:为几乎所有对象实例分配内存的区域
4.方法区:用于存储已被虚拟机加载的类信息、常量(static final)、静态变量(static)、即时编译器编译后的代码,是JVM规范中的一个逻辑概念,具体存放在哪里,由虚拟机实现。非堆
5.直接内存:使用操作系统的本地函数库分配的非堆内存,再通过Java的DirectByteBuffer对象引用这块内存
线程共享的区域:
堆、方法区、直接内存
线程隔离的区域:
程序计数器和栈
1.StackOverflowError出现的场景
线程的栈帧大小超出了jvm的设置的栈容量(-Xss可以设置虚拟机栈的容量,在HotSpot虚拟机中,不区分虚拟机栈和本地方法栈,所以在HotSpot虚拟机中-Xss设置的是栈大小),最常见的情况就是程序出现了错误的递归,导致在一个线程中栈帧的深度过大
JVM栈最大容量参数:-Xss2M
2.OutOfMemoryError出现的场景
1.堆:虚拟机中的对象,占用的内存容量大于JVM最大堆容量
JVM堆参数配置:
- 最小堆容量:-Xms2G。最大堆容量-Xmx4G
- 堆内存溢出dump文件:-XX:HeapDumpOnOutOfMemoryError
2.方法区内存溢出
在java1.6中的HotSpot虚拟机中,方法区用永久代实现。当永久代占用的内存大于JVM参数的永久代最大值时出现内存溢出
Java1.6-1.7的JVM永久代参数配置:
最小永久代:-XX:PermSize=500m 最大永久代:-XX:MaxPermSize=1000m
Java1.8中利用元空间实现方法区,永久代的概念被移除了(-XX:MaxPermSize失去了意义),使用参数:
最大元空间设置:-XX:MaxMetaspaceSize
3.直接内存溢出
直接内存容量大小默认与Java堆得最大值(-Xmx)相同,可以通过参数:-XX:MaxDirectMemorySize=1G指定
4.虚拟机栈和本地方法栈
创建的线程过多,亦或是JVM线程栈参数过大,导致操作系统无法继续创建新的线程,会出现OutOfMemoryError
3.Java进程占用内存总和
堆+线程个数*栈帧容量+方法区+直接内存+操作系统占用内存
参数配置:-Xmx + threadCount*-Xss+(-XX:MaxPermSize 或者 -XX:MaxMetaspaceSize)+-XXMaxDirectMemorySize
以上是关于OutOfMemoryError和StackOverflowError的主要内容,如果未能解决你的问题,请参考以下文章
什么是 OutOfMemoryError 以及如何调试和修复它