什么是 OOM

在 Java 中,OOM 是 java.lang.OutOfMemoryError 异常的缩写,简单来说是应用的内存用完了。

而这个内存,指代的是 JVM 管理的内存模型。

JVM 内存模型

JVM 在运行时管理的内存区域分别如下程序计数器。其作用是记录每个线程当前执行的字节码指令的位置,因为可能有多个线程并发执行不同的方法,所以程序计数器是每个线程私有的。

Java 虚拟机栈。Java 中方法的调用会为方法创建栈帧,然后在线程的 Java 虚拟机栈中进行出栈入栈,记录调用情况;除此,Java 虚拟机栈还会记录局部变量表,操作数栈等信息,同样为每个线程私有。

Java 堆内存。程序中创建的对象,便存储在 Java 堆内存中,其也是 GC 的主要地方,堆内存中的对象又按不同的 “生存” 情况分为新生代,老年代等。Java 堆内存为所有线程共有。

方法区 / Metaspace。该区域主要存放类的元信息,在 JDK 1.8 后新独立出来 Metaspace。

本地方法栈。为 natice 方法,调用本地操作系统类库提供的内存环境。

堆外内存。这一区域不属于 JVM 内存,是可直接访问的内存,如 NIO 会访问到这部分。

为什么会 OOM

发生 OOM,简单来说可总结为两个原因:分配给 JVM 的内存确实不够用

分配的内存是够用的,但是代码写的不好,多余的内存没有释放,最终导致内存不够用

OOM 类型

一般 OOM 分为三种类型java.lang.OutOfMemoryError: Java heap space。Java 堆内存溢出,此种情况最常见。

java.lang.OutOfMemoryError: PermGen space。Java 永久代溢出,即方法区溢出了。

java.lang.StackOverflowError。不会抛 OOM ERROR,但也是比较常见的 Java 内存溢出。

分析 OOM 思路

接下来简单总结,在线上环境遇到 OOM 时,分析定位问题的思路。寻找 GC 日志和 dump 文件。 这里有个问题,就是不知道线上应用有没有开启打印 GC 日志和 dump 文件,这里寻找的思路如下

// 1.查找对应的应用的 pid

jps -v // 输出所有 Java 应用,找对应 pid,或使用 ps -ef | grep xxx 来寻找

// 2.查看该 pid 启动应用时的 VM 参数

jinfo -flags pid

获取到的 VM 参数,可关注如下几项参数的情况

-XX:+HeapDumpOnOutOfMemoryError // 是否开启 OOM 时输出 dump 文件,+ 表示开启

-XX:HeapDumpPath=/data/logs // 若配置该项,dump 文件输出到该路径下

-XX:+PrintGCDetails // 是否打印 GC 详细信息

-XX:+PrintGCTimeStamps // 是否打印 GC 时间戳(基准形式)

-XX:+PrintGCDateStamps // 是否打印 GC 时间戳(日期形式)

-XX:+PrintTenuringDistribution // 在每次新生代 GC 时,输出幸存区中对象的年龄分布

-Xloggc:/data/logs // 若配置该项,GC 日志输出到该路径下若应用没有启用相应的参数输出日志,这里简单查看应用 JVM 内存使用情况的思路如下

// 1.查看应用 GC 次数及平均每次 GC 时间

jstat -gc pid 5000 // 每 5 秒显示一次 pid 的进程生成 GC 情况

// 2.查看 JVM 堆内存不同代的具体使用情况

jmap -heap pid同时,应该在这时加上对应的参数,见上面 [获取到的 VM 参数] 示例。

那么如何加上参数呢?

有几个方法可以设置。首先是加在 Tomcat 的启动文件上(/bin/catalina.sh),如下新增配置

JAVA_OPTS="-XX:+HeapDumpOnOutOfMemoryError ... "

因为我们是一个 Tomcat 只部署一个应用,这样配置在 Tomcat 启动文件上,其粒度便只针对当前应用。

除此之外,也可以配置在 Maven 启动文件上(%MAVEN_HOME%/bin/mvn),配置语法与上面类似。因为有多个应用使用同个 Maven,因此最后没有采用该种配置方法。

配置完参数后,重新发布应用,若下次有 OOM 情况出现,便可分析对应日志来定位具体问题。

脑图

参考文章

END

java oom分析_Java OOM 分析相关推荐

  1. java map 参数传递_Java参数传递分析

    Java之中的参数传递,只有按值传递!!! 传递类型 按值传递:就是把原来的参数的值,拷贝一份,将这个拷贝的值修改,而原来的旧的值不会修改. 引用传递:就是将参数的地址拿来使用,不去拷贝,直接在这个地 ...

  2. linux java内存分析_Java内存分析利器MAT使用详解

    这是一篇阅读MAT helper的笔记.Heap dump是Java进程在特定时间的一个内存快照.通常在触发heap dump之前会进行一次full gc,这样dump出来的内容就包含的是被gc后的对 ...

  3. java内存分析_java内存分析总结

    1.自带的jconsole工具. (1)如果是从命令行启动,使 JDK 在 PATH 上,运行 jconsole 即可. (2)如果从 GUI shell 启动,找到 JDK 安装路径,打开 bin ...

  4. java标量替换_JAVA逃逸分析、栈上分配、标量替换、同步消除

    一.逃逸分析 逃逸分析是编译语言中的一种优化分析,而不是一种优化的手段.通过对象的作用范围的分析,为其他优化手段提供分析数据从而进行优化. 逃逸分析包括: 全局变量赋值逃逸 方法返回值逃逸 实例引用发 ...

  5. java visualvm 教程_Java性能分析神器--VisualVM Launcher[1]

    Java性能分析神器1--VisualVM Launcher VisualVM 当你日复一日敲代码的时候,当你把各种各样的框架集成到一起的时候,看着大功告成成功运行的日志,有没有那么一丝丝迷茫和惆怅: ...

  6. java 堆 分析_Java堆分析 jmap+jhat

    Java堆分析 jmap+jhat 最近在使用DataSync做数据迁移,执行了10天+,进程还未结束,也未出现错误日志,所以就看看是不是哪里卡住了... jmap命令: -dump:[live,]f ...

  7. java 内部编码_Java 中文编码分析

    一.charAt 与 codePonitAt 我们知道 Java 内部使用的是 utf-16 作为它的 char.String 的字符编码方式,这里我们叫它内部字符集.而 utf-16 是变长编码,一 ...

  8. java 简单数组_Java 数组分析及简单实例

    Java 数组 一.什么是数组 数组?什么是数组?在我印象中的数组是应该这样的:通过new关键字创建并组装他们,通过使用整形索引值访问它的元素,并且它的尺寸是不可变的! 但是这只是数组的最表面的东西! ...

  9. java火焰评测_JAVA性能分析之使用火焰图

    随着业务的发展,使用接口提供的服务的业务越来越多,不同的业务对调用耗时的要求不同,当然,耗时越少越好.而近来已经有三四个调用方反映接口调用耗时太不稳定,代码上的优化已经做了很多,有效果,但还不够.同时 ...

最新文章

  1. 【计算机网络】网络安全 : 对称密钥密码体质 ( 数据加密标准 DES | DES 加密过程 | DES 保密性 | 三重 DES 加密 )
  2. 经典 MyBatis 面试题
  3. 集成测试CDI 1.0和Spring 3.1中的作用域bean
  4. 【汇编语言】记录一组数中负数的个数,8086与MIPS汇编程序
  5. WinNT/Win2000/WinXP中的远线程技术之一
  6. Jeewx 捷微管家操作配置文档(开源版本)
  7. Try using .loc[row_indexer,col_indexer] = value instead
  8. arcgis api 3.X 几种查询方式比较
  9. 对Java回调函数的理解
  10. 电脑系统怎么升级到win10?win7升级win10系统操作教程
  11. Win11系统桌面状态栏电池图标不显示怎么办?
  12. 【MATLAB笔记】绘制图中图
  13. android 动画-补间动画
  14. idea android 真机,intellij idea 设置用真机测试android
  15. 【小米手环7】使用 Zeus + 表盘自定义工具 为小米手环7开发和安装小程序
  16. Docker 上传镜像到docker hub
  17. 设置网页默认为360浏览器极速模式打开
  18. 解决Windows Server 2008 R2安装声卡驱动后还是提示无音频设备的问题
  19. 【渝粤题库】陕西师范大学165108 招聘与选拔管理 作业(高起专)
  20. nas 软件 性能测试,理论读写性能测试

热门文章

  1. STM32实战 1 | STM32Cube生态系统认识与介绍
  2. python3exe_用cxfreeze打包Python3.3成exe文件
  3. 卡尔曼滤波-数据融合
  4. 解决远程连接mysql出现10038问题心得
  5. threeJs搭建智慧园区
  6. mysql日期格式有哪些,mysql日期格式有哪些
  7. Linux的简单命令(转)
  8. C语言 itoa函数简单实现
  9. Python 线性插值
  10. 20170929校内训练