本文梳理常见的内存溢出情况, 以及如何查询解决.
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 把方法区放到了物理内存.
来源: http://www.bubuko.com/infodetail-3100262.html