堆(共享)
内存溢出
- 异常信息:java.lang.OutOfMemoryError: Java heap space
- 原因:Java堆用于存储对象实例,对象数量达到最大容量后产生内存溢出
- 设置:-verbose:gc -Xms20M -Xmx20M -Xmm10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
- 处理:
1)用内存映像分析工具如Eclipse Memory Analyzer对dump出来的堆转储快照进行分析,确定内存中的对象是否是必要的,也就是到底是内存泄漏(Memory Leak)还是内存溢出(Memory Overflow)
2)如果是内存泄漏,那么查看泄漏对象到GC Roots的引用链(对象与GC Roots的关联路径,有这条路径在,GC就不会去清理这个对象),再定位到泄漏代码
3)如果是内存溢出,那么检查JVM参数是否可以加大,检查代码上是否存在某些生命周期过长的情况以及其他减少运行期内存的方法
虚拟机栈和本地方法栈(线程私有)
满栈
- 异常信息:java.lang.StackOverflowError
- 原因:栈存储的是局部变量,当局部变量过多,栈深度大于虚拟机允许的深度时报异常
- 设置:-Xss128k(每个线程栈分配的内存)
内存溢出
- 异常信息:java.lang.OutOfMemoryError: unable to create new native thread
- 原因:线程扩展时无法申请空间,导致无法创建更多的线程
- 设置:-Xss128k
- 处理:
1)通过减少最大堆和减少栈容量(线程大小)来换取更多的线程
方法区(共享)
运行时常量池溢出
- 异常信息:java.lang.OutOfMemoryError: PermGen space
- 原因:常量池存储的是常量和静态变量
- 设置:-XX:PermSize和-XX:MaxPermSize
方法区溢出
- 异常信息:java.lang.OutOfMemoryError: PermGen space
- 原因:方法区存储的是Class相关的信息,一般是动态生成大量Class的应用中会遇到
本机直接内存
内存溢出
- 异常信息:java.lang.OutOfMemoryError
- 原因:直接内存在NIO中使用,NIO是一种基于通道和缓冲的IO方式,为了避免Java堆和Native堆来回复制数据,他使用Native函数直接分配内存,并通过DirectByteBuffer对象作为这块内存的引用,这个就是本机直接内存
- 设置:-XX:MaxDirectMemorySize
- 备注:OutOfMemoryError 后面不接是哪个内存块,那就是直接内存溢出