堆溢出
会出现java.lang.OutOfMemoryError,紧接着还会跟一条Java heap space,at…
先通过内存映像分析工具堆dump出来的堆快照分析,
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/flume-ng/dump
该路径必须已经存在
分清楚是内存泄漏还是内存溢出
对于内存泄漏,查一下GC Roots的引用链,掌握泄露对象的类型信息及GC Roots引用链的信息,定位出问题的地方
对于内存溢出,看看-Xms和-Xmx,看看能不能调大,从代码上检查是否有些对象生命周期过长等
虚拟机栈和本地方法溢出
Hotspot中不区分虚拟机栈和本地方法栈,所以对于它来说-Xoss(设置本地方法栈大小)没啥用,栈容量只由-Xss来设置
一般来说,默认的Xss够用了,而且即使爆栈也会有足够的提示来解决,有的32位系统受限于寻址能力,因为多线程引起爆栈,有时候需要减少Xmx和减少栈容量来换取更多的线程
运行时常量池溢出和方法区溢出
由于常量池分配在方法区内,可以通过-XX:MaxPermSize和-XX:MaxPermSize来限制方法区大小达到间接限制常量池的目的
运行时常量池溢出也会抛OOM,但是后面提示的信息是PermGen space,说明运行时常量池属于方法区,也就是Hotspot中用就带的一部分
本机直接内存溢出
可以通过-XX:MaxDirectMemorySize指定,如果不指定默认与Java堆的最大值-Xmx一样,虽然用DirectByteBuffer分配内存也会导致溢出,但是抛异常时只是通过计算得知无法分配,并没有真正向OS申请分配内存,真正申请分配内存的方法是unsafe.allocateMemory()