当JVM内存不足时,会抛出java.lang.OutOfMemoryError.

主要的OOM类型右:
Java heap space:堆空间不足
GC overhead limit exceeded : GC开销超出限制
Permgen space:永久代内存不足
Metaspace:元空间内存不足
Unable to create new native thread:无法创建新的本地线程
Out of swap space? : 交换空间内存不足
Kill process or sacrifice child

Java heap space:堆空间不足

通用解决方案:通过-Xmx设置更大的堆内存【该方式可能只是延迟报错的发生,如果不能从根本上找到原因,报错还是可能会发生】
进一步原因分析及解决方案:
流量/数据量峰值 : 可以考虑添加机器资源,或者做限流
内存泄漏 : 需要找到持有的对象,修改代码
创建了一个超大对象(通常是一个大数组) : 可以进行业务切分
代码示例
内存泄漏【-Xmx10m】
package oom;

import java.util.HashMap;
import java.util.Map;

/**

  • 内存泄露
    */
    public class JavaHeapSpace2 {

    public static void main(String[] args) {
    Map<Key,String> map = new HashMap<>();
    while (true) {
    Key key = new Key();
    if(!map.containsKey(key)) {
    map.put(key, “Java Overhead”);
    System.out.println(key);
    }
    }

    }
    }

class Key { }
创建了一个超大对象

oom.Key@2ef70cb4

oom.Key@457298d0
oom.Key@484b94f2
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at java.util.HashMap.resize(HashMap.java:704)
at java.util.HashMap.putVal(HashMap.java:663)
at java.util.HashMap.put(HashMap.java:612)
at oom.JavaHeapSpace2.main(JavaHeapSpace2.java:16)

View Result
View Result[-Xmx12m]
View Result[-Xmx35m]

package oom;

import java.lang.management.ManagementFactory;
import java.util.List;

public class JavaHeapSpace {

private static final int SIZE = 12 * 1024 * 2014;public static void main(String[] args) {List<String> inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();System.out.println("JVM Arguments : " + inputArguments);int[] arr = new int[SIZE];
}

}
GC overhead limit exceeded : GC开销超出限制

JVM Arguments : [-Xmx12m, -Dfile.encoding=GBK]
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at oom.JavaHeapSpace.main(JavaHeapSpace.java:13)

Process finished with exit code 1

JVM Arguments : [-Xmx35m,-Dfile.encoding=GBK]

Process finished with exit code 0
默认情况下,当应用程序花费超过98%的时间用来做GC并且回收了不到2%的堆内存时,会抛出java.lang.OutOfMemoryError:GC overhead limit exceeded错误。
此类问题的原因与解决方案跟 Java heap space 非常类似,可以参考上文
代码演示【使用默认的VM配置】
View Code
View Result
package oom;

import java.util.HashMap;
import java.util.Map;

public class JavaHeapSpace2 {

public static void main(String[] args) {Map<Key,String> map = new HashMap<>();while (true) {Key key = new Key();if(!map.containsKey(key)) {map.put(key, "Java Overhead");System.out.println(key);}}
}

}

class Key { }

oom.Key@61f7f66c
oom.Key@1da844d

oom.Key@792b37e7
oom.Key@3d8151c0Exception in thread “main” java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:265)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)

View Result

Permgen space:永久代内存不足
背景:永久代主要存储类的信息,比如:类加载引用、运行时常量池、字段、方法等。因此,Permgen的大小取决于被加载类的数量及类的大小。
原因:
加载了太多的类
加载了超大类
注意:JDK8已经完全移除永久代空间,取而代之的是元空间(Metaspace)

Metaspace:元空间内存不足
背景:Metaspace存储类的元数据信息
原因:
加载了太多的类
加载了超大类
解决方案
调整-XX:MaxMetaspaceSize参数
删除-XX:MaxMetaspaceSize参数,解除限制【默认是没有限制的。默认情况下,对于64位服务器端JVM,MetaspaceSize默认大小是21M(初始限制值),一旦达到这个限制值,FullGC将被触发进行类卸载,并且这个限制值将会被重置,新的限制值依赖于Metaspace的剩余容量。如果没有足够空间被释放,这个限制值将会上升。】
代码演示【JDK1.8】
View Code
View Result
package oom;

import javassist.CannotCompileException;
import javassist.ClassPool;

import java.lang.management.ManagementFactory;
import java.util.List;

public class Metaspace{

public static void main(String[] args) throws CannotCompileException {List<String> inputArguments = ManagementFactory.getRuntimeMXBean().getInputArguments();System.out.println("JVM Arguments : " + inputArguments);for (int i = 0; i < 100000000; i++) {ClassPool.getDefault().makeClass("User" + i).toClass();}
}

}

Unable to create new native thread:无法创建新的本地线程
背景:每个线程都需要一定的内存空间,当JVM向底层操作系统请求创建一个新的native线程时,如果没有足够的资源分配就会报这个错误
原因分析及解决方案:
线程数超过了OS最大线程数ulimit限制 : 调高 OS 层面的线程最大数 - 执行 ulimia-a 查看最大线程数限制,使用 ulimit-u xxx 调整最大线程数限制
线程数超过了本地线程最大数:限制线程池大小 ;
native内存不足 :
使用 -Xss 参数减少线程栈的大小
升级配置,为机器提供更多的内存
代码示例
View Code
View Result

JVM Arguments : [-XX:MaxMetaspaceSize=35m, -Dfile.encoding=GBK]
Exception in thread “main” javassist.CannotCompileException: by java.lang.OutOfMemoryError: Metaspace
at javassist.ClassPool.toClass(ClassPool.java:1099)
at javassist.ClassPool.toClass(ClassPool.java:1042)
at javassist.ClassPool.toClass(ClassPool.java:1000)
at javassist.CtClass.toClass(CtClass.java:1224)
at oom.Permgen.main(Permgen.java:16)
Caused by: java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
at java.lang.ClassLoader.defineClass(ClassLoader.java:642)
at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at javassist.ClassPool.toClass2(ClassPool.java:1112)
at javassist.ClassPool.toClass(ClassPool.java:1093)
… 4 more

View Result

A fatal error has been detected by the Java Runtime Environment:

EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x000000006a674447, pid=18648, tid=0x0000000000067b68

JRE version: Java™ SE Runtime Environment (8.0_171-b11) (build 1.8.0_171-b11)

Java VM: Java HotSpot™ 64-Bit Server VM (25.171-b11 mixed mode windows-amd64 compressed oops)

Problematic frame:

V [jvm.dll+0x214447][thread 424944 also had an error]

An unrecoverable stack overflow has occurred.
[thread 424964 also had an error]
An unrecoverable stack overflow has occurred.
[thread 424984 also had an error]
[thread 424992 also had an error]
An unrecoverable stack overflow has occurred.
[thread 424988 also had an error]
Exception in thread “main” java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:717)
at oom.UnableCreateThread.main(UnableCreateThread.java:14)

View Result
Out of swap space? :

交换空间内存不足
背景:虚拟内存(Virtual Memory)由物理内存(Physical Memory)和交换空间(Swap Space)两部分组成。在JVM请求的总内存大于可用物理内存的情况下,操作系统会将内存中的数据交换到磁盘上去。当交换空间也将耗尽时就会报 Outof swap space? 错误。
原因分析及解决方案:【往往是由操作系统级别的问题引起的】
操作系统配置的交换空间不足 :
加交换空间【对交换空间运行垃圾回收算法会使GC暂停的时间增加几个数量级,因此使用增加交换空间的方法】
升级机器以包含更多内存
系统上的另一个进程消耗所有内存资源:如果应用部署在JVM需要同其他进程激烈竞争获取资源的物理机上,建议将服务隔离到单独的虚拟机中
本地内存泄漏导致应用程序失败: 优化应用程序以减少其内存占用

Kill process or sacrifice child
背景:操作系统是建立在进程的概念之上,这些进程在内核中作业,其中有一个非常特殊的进程,名叫“内存杀手(Out of memory killer)”。当内核检测到系统内存不足时,OOM killer被激活,然后选择一个进程杀掉。
原因分析:程序占用大量系统内存导致其他进程没有可用内存
解决方案:
调整OOM Killer配置
升级机器以包含更多内存

你可以通过修改各种启动参数来“快速修复”这些内存溢出错误,但你需要正确区分你是否只是推迟或者隐藏了java.lang.OutOfMemoryError的症状。如果你的应用程序确实存在内存泄漏或者本来就加载了一些不合理的类,那么所有这些配置都只是推迟问题出现的时间而已,实际也不会改善任何东西。

Java内存溢出(OOM)分析相关推荐

  1. Java内存溢出OOM之dump分析

    目录 内存泄露 内存溢出 1.Java堆内存异常 报错方式 原因 2.Java栈内存异常 报错方式 原因 3.方法区内存异常 报错方式 原因 解决思路 生成dump文件三种方式 dump生成 jvis ...

  2. Java内存溢出OOM使用Mat分析

    示例 package com.rumenz;import java.util.ArrayList; import java.util.List;public class OutOfMemory {pu ...

  3. Java内存溢出(OOM)异常完全指南

    原文:http://luecsc.blog.51cto.com/2219432/1948800 这也许是目前最为完整的Java OOM异常的解决指南. 1.Java.lang.OutOfMemoryE ...

  4. java 内存溢出分析_用一段时间后java内存溢出问题分析(转)

    几乎每个月都有出现因为内存溢出的问题,除了需要多分配内存外, 是不是要考虑对代码进行一些处理.. 下面是参考网络资源总结的一些在Java编程中尽可能要做到的一些地方. 1.尽量在合适的场合使用单例 使 ...

  5. java 内存溢出问题分析过程

    C 节点的子树就是所有被 C 支配的节点的集合,也称为 C 的 <一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义>开源 Retained Set. 由 ...

  6. Java常见内存溢出(OOM)解决方案

    Java 常见内存溢出(OOM)解决方案 一,jvm内存区域   1,         程序计数器 一块很小的内存空间,作用是当前线程所执行的字节码的行号指示器. 2,         java栈 与 ...

  7. java内存溢出分析工具:jmap使用实战

    java内存溢出分析工具:jmap使用实战 在一次解决系统tomcat老是内存撑到头,然后崩溃的问题时,使用到了jmap.  1 使用命令  在环境是linux+jdk1.5以上,这个工具是自带的,路 ...

  8. Java内存溢出问题排查分析

    目录 前言 一.MAT(Memory Analyzer Tool) 二.软件初识 三.捕获dump文件 1.主动方式 2.被动方式 四.分析dump文件 总结 前言 项目运行过程中,我们可能会遇到Ja ...

  9. Java内存溢出分析

    内存溢出与数据库锁表的问题,可以说是开发人员的噩梦,一般的程序异常,总是可以知道在什么时候或是在什么操作步骤上出现了异常,而且根据堆栈信息也很容易定位到程序中是某处出现了问题.内存溢出与锁表则不然,一 ...

最新文章

  1. Android自定义ViewGroup基本步骤
  2. 【POJ】3617 Best Cow Line (字典序 字符串)
  3. js深度解析url地址
  4. js调试,输出函数调用顺序
  5. [Python] NotImplemented 和 NotImplementedError 区别
  6. Zookeeper常用命令行及API
  7. 实现原理 扫描枪_条码扫描枪工作原理
  8. Visual Studio 2005 提示“试图运行项目时出错:无法启动调试。绑定句柄无效”~[解决方案]...
  9. python学习——和python的第一次亲密接触
  10. html网页中加载pdf,在HTML页面中嵌入本地PDF
  11. linux 查看硬盘序列号
  12. cdr怎么抠图轮廓线条_CDR怎么抠图?CorelDRAW快速抠图方法
  13. python批量删缩进_鬼畜小姐姐+野狼disco,十分钟教你如何用Python剪辑一个牛逼的抖音小视频?...
  14. 人机交互-2-交互设计的原则与方法
  15. mysql加锁分析 何登成_何登成的技术博客 ? MySQL 加锁处理分析
  16. 安卓恶意锁屏APP分析
  17. kepware KEPServerEX与欧姆龙NX系列PLC通讯-Omron NJ Ethernet
  18. 2022最新树莓派4B学习笔记:系统备份 OpenCV SPI TFT HTML
  19. 为什么串口传输速度比并口快?
  20. java编写桌球游戏素材小球图片_小球图片_小球模板_小球设计素材下载

热门文章

  1. Clion快捷键、代码格式、字体大小设置
  2. Server hangs with message uhci_hcd XXXX:XX:XX:.X: Unlink after no-IRQ? Controller is probably using
  3. (00XX系列)摸摸Windows的SEH
  4. 二维码WIFI自动连接生成格式
  5. bootstrap布局 网格系统
  6. 推荐一些适合软件测试从业者的书,以及如何找书
  7. Android 9.0 AutoMotive模块之CarService
  8. 打造最具创新力的开源数据库社区 | 【重庆】openGauss Meetup圆满结束
  9. 三相桥式全控整流电路simulink仿真_不可控整流电路知识介绍
  10. 三相全控桥式整流matlab仿真,基于matlab的三相桥式全控整流电路的仿真研究