目录
一:常见的 OOM 问题
1:java.lang.OutOfMemoryError: ......java heap space.....
代码存储是否有问题,亦或者适当调整-Xmx和-Xms
2:java.lang.OutOfMemoryError:GC over head limit exceeded
系统处于高频的GC状态,而且回收的效果依然不佳的情况
3:java.lang.OutOfMemoryError: PermGen space
Permanent Generation空间满:老年代
当系统中要加载的类、反射的类和调用的方法较多时,Permanent Generation可能会被占满,在未配置为采用CMS GC的情况下会执行Full GC。如果经过Full GC仍然回收不了,那么JVM会抛出该错误信息
解决:第三方包非常多、或代码中使用了大量的常量、动态代码加载等,导致常量池的膨胀
增加-XX:PermSize和-XX:MaxPermSize的大小。
4:java.lang.OutOfMemoryError: Direct buffer memory
直接或间接使用了ByteBuffer中的allocateDirect方法的时候,而不做clear的时候就会出现类似的问题
5:java.lang.StackOverflowError
就是-Xss太小了
六:java.lang.OutOfMemoryError: unable to create new native thread
要么是内存本身就不够,要么heap的空间设置得太大了
参考链接:https://blog.csdn.net/zimengaaaaaa/article/details/89182336
二:相关调优参数
1.java虚拟机对外提供的可配置堆区的参数:
-Xmx:表示java虚拟机堆区内存可被分配的最大上限,通常为操作系统可用内存的1/64大小即可
-Xms:表示java虚拟机堆区内存初始内存分配的大小,通常为操作系统可用内存的1/4大小
-XX:newSize:表示新生代初始内存的大小,应该小于 -Xms的值;
-XX:MaxnewSize:表示新生代可被分配的内存的最大上限;当然这个值应该小于 -Xmx的值;
-Xmn:至于这个参数则是对 -XX:newSize、-XX:MaxnewSize两个参数的同时配置,也就是说如果通过-Xmn来配置新生代的内存大小,那么-XX:newSize = -XX:MaxnewSize = -Xmn,虽然会很方便,但需要注意的是这个参数是在JDK1.4版本以后才使用的。
-Xss 规定了每个线程堆栈的大小。一般情况下256K是足够了。影响了此进程中并发线程数大小。
2.java虚拟机对非堆区内存配置的参数:
-XX:PermSize:表示非堆区初始内存分配大小,其缩写为permanent size(持久化内存)
-XX:MaxPermSize:表示对非堆区分配的内存的最大上限。
例子:
-Xmx2048m 等价于-XX:MaxHeapSize=2048m,设置JVM最大堆内存为2048m
-Xms512m 等价于-XX:InitialHeapSize=512m,设置JVM最初是堆内存为512m
三:JVM的堆(Heap)和非堆(Non-heap)内存
1.堆:
堆是运行时数据区域,所有类实例和数组的内存均从此处分配。堆是在 Java 虚拟机启动时创建的
堆就是Java代码可及的内存,是留给开发人员使用的
2.非堆:
在JVM中堆之外的内存称为非堆内存(Non-heap memory)
非堆就是JVM留给 自己用的,所有方法区、JVM内部处理或优化所需的内存(如JIT编译后的代码缓存)、每个类结构(如运行时常数池、字段和方法数据)以及方法和构造方法 的代码都在非堆内存中。