Java进程 OOM的多种情况


摘要

OOM 其实有多种:

第一类是JVM原生自发处理的, 这种也分为多种情况.
1. 堆区使用了比较多,并且大部分对象都还有引用, GC不出来可用内存,
这是要给对象申请较大的内存空间时就会出现OOM的报错.
2. 除了IP 下一条命令指针的内存的区域, 其他任何区域都存在OOM的风险.
比如metadata,codecache,以及栈空间, 当然metadata一般时无限制的.
栈空间一般是stack over flow的提示信息. 第二类 操作系统进行的处理.
当系统的内存使用较高的时候, 剩余空间几乎没有
此时如果有JAVA本服务的线程,或者是其他进程要跟操作系统申请内存使用.
操作系统发现内存已经不足以支撑, 就会选择oom_score 得分比较高的进程进行kill
如果正好关闭了swap, 不会进行swapout/swapin的操作, 系统可能使用的很流畅.
突然就会宕机. 这种通过分析JVM是较难进行处理的.

问题现象

今天下午现场一台机器突然宕机连不上.
运维同事立即进行了服务启动.
晚上时有人反馈系统出现宕机影响使用.
这边进行了一下简单的分析. 结果其实都是摘要里面的.
但是想把过程简单描述一下, 以便备忘.

分析过程

方法很简单通过如下命令就可以
cat /var/log/messages |grep out_of_memory+ -C 20 其实我这边还可以通过
dmesg -T |grep -i oom 进行查看
但是发现不如上面一个命令系统详实. 配合 系统的日志就可以进行分析.

系统日志信息

Mar 15 14:58:52 localhost kernel: OkHttp Connecti invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
Mar 15 14:58:52 localhost kernel: OkHttp Connecti cpuset=/ mems_allowed=0
Mar 15 14:58:52 localhost kernel: CPU: 4 PID: 23890 Comm: OkHttp Connecti Kdump: loaded Not tainted 3.10.0-1127.el7.x86_64 #1
Mar 15 14:58:52 localhost kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 12/12/2018
Mar 15 14:58:52 localhost kernel: Call Trace:
.................................
Mar 15 14:58:52 localhost kernel: Out of memory: Kill process 25813 (java) score 757 or sacrifice child
Mar 15 14:58:52 localhost kernel: Killed process 23697 (sh), UID 0, total-vm:113284kB, anon-rss:184kB, file-rss:0kB, shmem-rss:0kB
Mar 15 14:58:52 localhost kernel: Spring session invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0
Mar 15 14:58:52 localhost kernel: Spring session cpuset=/ mems_allowed=0
Mar 15 14:58:52 localhost kernel: CPU: 6 PID: 15972 Comm: Spring session Kdump: loaded Not tainted 3.10.0-1127.el7.x86_64 #1
Mar 15 14:58:52 localhost kernel: Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 12/12/2018
Mar 15 14:58:52 localhost kernel: Call Trace:
Mar 15 14:58:52 localhost kernel: Call Trace:
Mar 15 14:58:52 localhost kernel: [<ffffffffaf97ff85>] dump_stack+0x19/0x1b
Mar 15 14:58:52 localhost kernel: [<ffffffffaf97a8a3>] dump_header+0x90/0x229
Mar 15 14:58:52 localhost kernel: [<ffffffffaf306ce2>] ? ktime_get_ts64+0x52/0xf0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3c246e>] oom_kill_process+0x25e/0x3f0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf333a41>] ? cpuset_mems_allowed_intersects+0x21/0x30
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3c1ecd>] ? oom_unkillable_task+0xcd/0x120
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3c1f76>] ? find_lock_task_mm+0x56/0xc0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3c2cc6>] out_of_memory+0x4b6/0x4f0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf97b3c0>] __alloc_pages_slowpath+0x5db/0x729
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3c9146>] __alloc_pages_nodemask+0x436/0x450
Mar 15 14:58:52 localhost kernel: [<ffffffffaf418e18>] alloc_pages_current+0x98/0x110
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3be377>] __page_cache_alloc+0x97/0xb0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3c0f30>] filemap_fault+0x270/0x420
Mar 15 14:58:52 localhost kernel: [<ffffffffc037da4e>] __xfs_filemap_fault+0x7e/0x1d0 [xfs]
Mar 15 14:58:52 localhost kernel: [<ffffffffc037dc4c>] xfs_filemap_fault+0x2c/0x30 [xfs]
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3edeea>] __do_fault.isra.61+0x8a/0x100
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3ee49c>] do_read_fault.isra.63+0x4c/0x1b0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf3f5d00>] handle_mm_fault+0xa20/0xfb0
Mar 15 14:58:52 localhost kernel: [<ffffffffaf98d653>] __do_page_fault+0x213/0x500
Mar 15 14:58:52 localhost kernel: [<ffffffffaf98d975>] do_page_fault+0x35/0x90
Mar 15 14:58:52 localhost kernel: [<ffffffffaf989778>] page_fault+0x28/0x30

进程信息

可以看到 上面一个被kill的信息为:
Out of memory: Kill process 25813
查看系统宕机之前的日志就可以确定是否是本进程
2023-03-15 14:47:56,845 localhost.localdomain ERROR [25813.85ec182.314.1]
[Schd] org.hibernate.engine.jdbc.spi.SqlExceptionHelper 看到 ERROR 后面的第一个就是进程信息,致辞确认是被linux系统给kill了.

问题原因分析与对策

1. GC日志里面没有任何Full GC多次出现的现象.
宕机之前系统运行是非常稳定的.
2. 之前系统多次出现过swap分区使用过多的情况.导致卡顿.
为了避免过于卡顿影响业务,已经将swap分区关闭.
3. dmesg 发现系统经常有OOM的情况. 所以分析下来,在不特备影响系统性能的情况下只有两种解决策略:
1. 适当降低jvm的堆区, 也就是降低 -Xms和-Xmx 给其他使用者空闲出来一部分资源.
2. 提高资源配置. 加大内存, 避免出现宕机的问题.

问题的延伸思考

1. 一个机器. 可以分配多少内存给JVM的堆区?
2. 内存应该如何分配,堆区,栈区,方法区,元数据区,本地内存等的配置. 以及留出部分内存给想系统和文件缓存使用.
3. docker 容器模式下. 如果使用ramMaxPercentage 的模式进行设置. 堆区太小肯定性能不好, 太大了之后FullGC的STW时间需要控制.
之前对功能还有自动化的环境进行过 NMT的内存跟踪, 堆区,一般占用总Java进程的75左右的内存.
所以理论上 排除到系统必须的内存和一定的文件缓存之后. 堆区应该不能占用超过七成的可用内存
避免出现宕机的情况.

Java进程 OOM的多种情况的更多相关文章

  1. 通过JDK常用工具监控Java进程的内存占用情况

    目录 1 JDK 工具的使用 2 查看 GC 日志信息 3 添加 JMS 远程监控 Tomcat是一款常用的Web容器, 它是运行在 JVM(Java Virtual Machine) 中的一个Jav ...

  2. linux 查看Java 进程的内存使用情况

    top -b -n 1 | grep java| awk '{print "PID:"$1",mem:"$6",CPU percent:"$ ...

  3. 性能分析(1)- Java 进程导致 CPU 使用率升高,问题怎么定位?

    性能分析小案例系列,可以通过下面链接查看哦 ps:这些分析小案例不能保证百分比正确,是博主学习过程中的总结,仅做参考 前提 本机有一个很占用 CPU 的项目,放在了 Tomcat 下启动着 如何定位 ...

  4. java进程被OOM干掉问题记录

    异常现象:用户环境部署了一台iserver,访问一阵后,进程没了   分析: 1.bin目录下没有崩溃日志,在tomcat的访问日志里面也没有看到有用的信息.iserver.log里面也没有信息 2. ...

  5. 【20180129】java进程经常OOM,扩容swap。

    导读:线上一台服务器专门做为公司内部apk打包服务,由于app的业务和功能与时俱增,apk打包需要依赖的资源越来越多,最近这几天每次apk打包的时候都会由于OOM导致打包失败.由于apk打包业务并不是 ...

  6. Java进程&线程(整理)

    Java进程&线程 程序:程序员写的代码,就是代码,不运行好像不会发生什么: 进程:一个进程可以理解为"运行的"一个程序,当我们启动一个java程序后,对应的jvm就会创建 ...

  7. Java进程&线程(一)

    Java进程&线程 程序:程序员写的代码,就是代码,不运行好像不会发生什么: 进程:一个进程可以理解为"运行的"一个程序,当我们启动一个java程序后,对应的jvm就会创建 ...

  8. JVM源码分析之一个Java进程究竟能创建多少线程

    JVM源码分析之一个Java进程究竟能创建多少线程 原创: 寒泉子 你假笨 2016-12-06 概述 虽然这篇文章的标题打着JVM源码分析的旗号,不过本文不仅仅从JVM源码角度来分析,更多的来自于L ...

  9. 分析java进程假死状况

    摘自: http://www.myexception.cn/internet/2044496.html 分析java进程假死情况 1 引言 1.1 编写目的 为了方便大家以后发现进程假死的时候能够正常 ...

  10. 如何优雅地停止Java进程

    目录 理解停止Java进程的本质 应该如何正确地停止Java进程 如何注册关闭钩子 使用关闭钩子的注意事项 信号量机制 总结 理解停止Java进程的本质 我们知道,Java程序的运行需要一个运行时环境 ...

随机推荐

  1. C语言编程需要掌握的核心要点有哪些? 编程大神为你总结了这20个

    摘要:C语言作为编程的入门语言,学习者如何快速掌握其核心知识点,面对茫茫书海,似乎有点迷茫.为了让各位快速地掌握C语言的知识内容,在这里对相关的知识点进行了归纳. 引言 笔者有十余年的C++开发经验, ...

  2. GaussDB技术解读丨数据库迁移创新实践

    本文分享自华为云社区<DTCC 2023专家解读丨GaussDB技术解读系列之数据库迁移创新实践>,作者:GaussDB 数据库. 近日,以"数智赋能 共筑未来"为主题 ...

  3. 拥抱时序数据库,构筑IoT时代下智慧康养数据存储底座

    摘要:在HDZ城市行广州站中,来自华为云华为云数据库创新Lab向宇从时序数据库的技术角度,解读一下华为云时序数据库GaussDB(for Influx)如何应用在智慧健康养老行业. 本文分享自华为云社 ...

  4. 带你掌握Visual Studio Code的格式化程序

    摘要:Visual Studio Code 中的所有语言都可以使用其中一种自动格式化程序进行格式化,并且 Python 扩展还支持 linter. 本文分享自华为云社区<Visual Studi ...

  5. 你知道,什么时候用Vue计算属性吗?

    摘要:当我们处理复杂逻辑时,都应该使用计算属性. 本文分享自华为云社区<深入理解计算属性,知道什么时候该用Vue计算属性吗?>,作者: 前端老实人 . 计算属性 有些时候,我们在模板中放入 ...

  6. vue2升级vue3: h、createVNode、render、createApp使用

    h.createVNode 杂乱笔记,凑合着看,不喜勿喷! h 函数是什么 h 函数本质就是 createElement() 的简写,作用是根据配置创建对应的虚拟节点,在vue 中占有极其重要的地位! ...

  7. 使用 cron4j-solon-plugin 开发定时任务(新)

    (一)新建一个 maven 空项目 (二)添加 maven 引用 <dependency> <groupId>org.noear</groupId> <art ...

  8. Solon Aop 特色开发(5)切面与环绕拦截

    Solon,更小.更快.更自由!本系列专门介绍Solon Aop方面的特色: <Solon Aop 特色开发(1)注入或手动获取配置> <Solon Aop 特色开发(2)注入或手动 ...

  9. Bert不完全手册4. 绕开BERT的MASK策略?XLNET & ELECTRA

    基于随机token MASK是Bert能实现双向上下文信息编码的核心.但是MASK策略本身存在一些问题 MASK的不一致性:MASK只在预训练任务中存在,在微调中不存在,Bert只是通过替换部分的随机 ...

  10. rem在手机移动端app中的兼容适配问题

    这是我之前一直使用的第一种rem方案.贴代码 1 <script> 2 // 适用于750的设计稿 3 var iScale = 1; 4 // 通过页面加载的时候去获取用户设备的物理像素 ...