本文梳理常见的内存溢出情况,以及如何查询解决。
Java堆溢出
1.设置参数
-XX:+HeapDumpOnOutOfMemoryError
2.该参数可以在堆内存溢出是保存快照以便于进行分析。
思路:
(1)分析转存快照,判断一下泄露对象到GC Roots的引用链,确定一下为啥GC无法回收,从而确定代码是否有问题。
(2)如果代码没有问题,说明现在的内存不够用,调整一下 -Xms和-Xmx。
虚拟机栈和本地方法栈溢出
hotspot中这两个是一起的都有统一参数控制
1.设置参数
-Xss
2.虚拟机规范
(1)线程请求深度超过虚拟机运行最大深度,抛出StackOverflowError异常。
(2)栈扩展是无法获取到更大内存,抛出OutOfMemoryError异常。
这两种本质上一样,一般都是第一种异常。
3.内存占用换算
32位windows限制为2G,减去堆(最大-Xmx)和方法区(MaxPermSize)空间,还有程序计数器空间(可忽略),剩下的就是栈的空间。
栈帧的大小和线程数量成反比,每个栈的容量越大线程数量就越少。
方法区和运行时常量池溢出
1.设置参数
-XX:PermSize -XX:MaxPermSize
2.方法区中类的来源
(1)启动加载
(2)运行时通过反射和动态代理生成
string.intern()是本地方法,原理在JVM原理里说过。
方法区GC条件很苛刻,不像对象回收,所以1.7之前这里出现了很多问题。1.8把方法区放到了物理内存。