OOM全程Out Of Memory,意思是JVM里没有足够的空间供使用,并且垃圾回收器也没有垃圾可回收就会抛出这个error。
OOM原因
1.内存分配太少,可以通过修改JVM参数来修复。
2.未及时释放资源,造成内存泄露或内存溢出。
内存泄漏:使用完的资源未及时释放导致该空间无法回收,并且无法分配给别人使用。
内存溢出:申请的内存超过JVM能提供的空间大小。
OOM类型
JVM内存模型:
1.程序计数器:记录程序当前执行位置。
2.虚拟机栈:存放栈帧,栈的入栈和出栈对应方法的进入和退出。
3.native方法栈:存放本地native方法。
4.堆:存放程序运行过程中产生的对象。
5.方法区:存储JVM中已经被加载好的类信息,常量,静态变量等。
6.运行时常量池:方法区的一部分,存储常量信息。
7.直接内存:可以直接访问内存。
按照JVM规范除程序计数器不会抛出OOM,其他都有可能抛出OOM
常见的OOM类型:
1.java.lang.OutOfMemoryError: Java heap space
堆内存溢出,一般由内存泄漏或内存参数配置不合理造成,需要通过内存监控软件查找泄漏的代码,参数配置可以通过修改虚拟机参数-xms -xms。
2.java.lang.OutOfMemoryError: PermGen space
永久代溢出,即方法区溢出,一般出现于大量Class或者jsp页面,或者使用了CGlib等反射机制的情况,可以通过修改方法区的大小,如-XX:PermSize=64m -XX:MaxPermSize=256m这些参数。
3.java.lang.StackOverflowError
虚拟机栈溢出,一般会出现与递归出现死循环或者深度递归,栈太小也可能会出现这种情况,可以通过修改 -Xss参数来设置栈的大小。
OOM分析
通过设置JVM的-XX:+HeapDumpOnOutOfMemoryError参数设定当发生OOM时会自动dump出堆信息
dump出堆信息后对其生成的文件进行分析找到OOM原因。
mat: eclipse memory analyzer, 基于eclipse RCP的内存分析工具。
OOM 就是内存被吃光,先 dump 再重启,用 MAT 看谁在占,改代码或调大 -Xmx 解决。