【银河麒麟服务器操作系统】java进程oom现象分析及处理建议

了解银河麒麟操作系统更多全新产品,请点击访问麒麟软件产品专区:https://product.kylinos.cn

现象描述

某服务器系统升级内核至4.19.90-25.22.v2101版本后仍会触发oom导致java进程被kill。

现象分析

oom现象分析

系统messages日志分析,故障时间2024.3.2 13:45左右,如图1:

图1

从下面的日志信息,可以看到java进程是在内核采用GFP_KERNEL|__GFP_COMP分配order=3也就是2的3次方,8个连续页的时候,系统无法提供对应大小的连续内存页,导致oom产生并选择java进程进行kill掉了。

现在来分析这一现像是否为正常现像(因为oom是内核的正常的机制),GFP_KERNEL的首先内存管理区为ZONE_NORMAL。从日志可以看出,当前系统一共有3个内存管理区,分别是ZONE_DMA、ZONE_DMA32和ZONE_NORMAL。接下来分析这个3个内存管理区的内存使用情况:

1)ZONE_DMA的空闲内存是15876kB , 最低水位是32k,低水位是44k, 高水位是56k, 空闲内存远大于高水位,所以kswapd是不会启动回收的,但是Linux内核有一个对低端内存管理区的保护机制,lowmem_reserve中有体现,加上保护机制,最低水位为:32K + 30759*4KB=123068KB,这个数据比空闲内存15876KB要大了,所以ZONE_DMA是不能分配成功的。

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126208] Mem-Info:

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126213] active_anon:1656544 inactive_anon:541287 isolated_anon:0#012 active_file:307018 inactive_file:548893 isolated_file:0#012 unevictable:0 dirty:136 writeback:0 unstable:0#012 slab_reclaimable:3601440 slab_unreclaimable:525232#012 mapped:39889 shmem:22418 pagetables:10064 bounce:0#012 free:124343 free_pcp:63 free_cma:0

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126215] Node 0 active_anon:6626176kB inactive_anon:2165148kB active_file:1228072kB inactive_file:2195572kB unevictable:0kB isolated(anon):0kB isolated(file):0kB mapped:159556kB dirty:544kB writeback:0kB shmem:89672kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 6649856kB writeback_tmp:0kB unstable:0kB all_unreclaimable? no

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126216] Node 0 DMA free:15876kB min:32kB low:44kB high:56kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:15992kB managed:15908kB mlocked:0kB kernel_stack:0kB pagetables:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126218] lowmem_reserve[]: 0 2689 30759 30759 30759

2)ZONE_DMA32的空闲内存是160984kB , 最低水位是5904k,低水位是8656k, 高水位是11408k, 空闲内存远大于高水位,所以kswapd是不会启动回收的,但和DMA区域一样加上lowmem_reserve保护机制,最低水位为:5904K + 28069*4KB=128940KB。

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126220] Node 0 DMA32 free:160984kB min:5904kB low:8656kB high:11408kB active_anon:327188kB inactive_anon:52060kB active_file:9776kB inactive_file:17044kB unevictable:0kB writepending:0kB present:3128832kB managed:2801120kB mlocked:0kB kernel_stack:3488kB pagetables:1368kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126223] lowmem_reserve[]: 0 0 28069 28069 28069

单纯从空闲内存大小来看似乎可以从DMA32区域分配出java进程所需的内存,但我们实际查看ZONE_DMA32的内存分布,空闲的160984kb内存大多为低阶的内存页。最大只可提供16KB即order=2(2^2*4K=16K)的连续内存页,无法满足java进程order=3的连续内存页请求。

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126233] Node 0 DMA32: 15760*4kB (UME) 5137*8kB (UE) 3547*16kB (UE) 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 160888kB

3)最后ZONE Normal的空闲内存是320512kb, 最低水位是61640k,低水位是90380k, 高水位是119120k, 空闲内存高于高水位,所以kswapd是不会启动回收的。

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126224] Node 0 Normal free:320512kB min:61640kB low:90380kB high:119120kB active_anon:6298988kB inactive_anon:2113088kB active_file:1218296kB inactive_file:2178680kB unevictable:0kB writepending:544kB present:30408704kB managed:28750204kB mlocked:0kB kernel_stack:41728kB pagetables:38888kB bounce:0kB free_pcp:252kB local_pcp:0kB free_cma:0kB

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126227] lowmem_reserve[]: 0 0 0 0 0

但同ZONE_DMA32一样,当我们实际查看这320512kb空闲内存的内存详情时,我们发现它同样最大只可提供16KB即order=2(2^2*4K=16K)的连续内存页,无法满足java进程order=3的连续内存页请求。

Mar 22 13:45:18 wzhapp13 kernel: [6229155.126237] Node 0 Normal: 10802*4kB (UME) 20894*8kB (UE) 6979*16kB (UE) 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 322024kB

从以上信息来看,本次触发OOM的原因和之前类似,都是系统内存碎片化,空闲内存高于内存回收水位但无法提供进程申请的较大阶数的连续内存页。

但不同的是,之前x86服务器是由于内核bug导致managed统计错位,从而使得Normal区域的内存回收水位线较小,而升级内核则不存在这个bug。只是当前默认的67584KB min_free_kbytes和实际业务场景不太符合。

min_free_kbytes参数分析

从OOM日志来看java进程需要申请较大的连续内存,而当前内存水位线较低,触发OOM时ZONE Normal虽有320512kb空闲内存但都是零散的,这和内存水位线的大小有关。

vm.min_free_kbytes是一个Linux重要的内核参数,用于控制系统可用内存的最小空闲大小。它指定了内核应该保留的空闲内存页面的数量(以KB为单位),以便能够及时满足系统的需要。

当系统运行过程中需要更多的内存时,从空闲页面中分配内存是一种快速且高效的方式。vm.min_free_kbytes参数的存在是为了确保系统在处理高内存压力时仍然具有足够的可用内存提供给内核、驱动等关键应用使用,这部分预留内存用户态应用通常无法申请。

同时vm.min_free_kbytes的设置衍生出了不同的内存回收水位,默认的内存回收水位计算方式如下:

1、watermark[min] = min_free_kbytes

2、watermark[low] = watermark[min] * 5 / 4

3、watermark[high] = watermark[min] * 3 / 2

当系统剩余空闲内存大于 high水位时,表示此时系统内存足够,不会进行内存回收;当系统剩余空闲内存内存小于low水位 时,表示此时内存存在压力,会触发 kswapd 进行后台内存回收,直到 pages_high 为止;当系统剩余空闲内存内存小于 min 水位时,表示此时用户内存耗尽,会触发直接内存回收,进程被阻塞。若是直接内存回收等方式还是无法释放出应用所需申请的连续内存时,就将触发OOM,通过强制杀死其他占用大量内存的进程来释放内存。

min_free_kbytes设的越大,watermark的线越高,同时三个线之间的buffer量也相应会增加。这意味着会较早的启动kswapd进行回收,且每次都会回收上来较多的内存(直至watermark[high]才会停止),但这也会使得系统预留过多的空闲内存,从而在一定程度上降低了应用程序可使用的内存量。

min_free_kbytes设的过小,则会导致系统预留内存过小。这不仅会导致在内存压力较大,空闲内存不足时内核、驱动以及其他GFP-AOTOMIC这种不可等待的内存申请无法进行。由于每次内存回收都是到watermark[high]就停止了,较低的min_free_kbytes容易导致每次进行内存回收时都是回收的零散内存,而未回收大块的连续内存,从而引起系统内存碎片化。

总结

综上所述,本次触发OOM的原因和之前的情况较为类似,都是系统内存回收水位线较小、内存碎片化,空闲内存高于内存回收水位但无法提供进程申请的较大阶数的连续内存页。

但不同的是,之前x86服务器是由于内核bug导致managed统计错位,从而使得Normal区域的内存回收水位线较小。而升级内核后则不存在这个bug,只是当前默认的67584KB min_free_kbytes和实际业务场景不太符合。

对该问题,推荐修改watermark_scale_factor的值,调大min、low、high三条内存回收水位线的差距,使得系统在空闲内存不足时更早、更多地进行内存回收;之后对于内存碎片化的情况,我们建议可以在业务空闲时指定定时任务规整内存。

后续计划及建议

  • 修改watermark_scale_factor的值来调大min、low、high三条内存回收水位线的差距,具体步骤如下。

打开sysctl.conf配置文件:vim /etc/sysctl.conf

在其中手动添加vm.watermark_scale_factor = XX (该值推荐设置为50-75)

完成修改后生效配置:sysctl -p

查询参数看是否修改完成:cat /proc/sys/vm/watermark_scale_factor 或 sysctl -a |grep watermark_scale_factor

  • 对于内存碎片化的情况,如果系统内存高碎片化情况较为频繁,条件允许的情况下,我们建议在业务空闲时手动进行异步内存规整。

root用户执行echo 1 > /proc/sys/vm/compact_memory即可,若服务器业务较为规律,推荐挑选一天中的业务空闲时间直接写入定时任务执行。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/48334.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据编织 Data Fabric:解决“数据孤岛”的新思路

一个不争的事实是,企业内部数据孤岛的形成,根因在于业务发展的复杂性与技术迭代的快速性导致。具体而言,随着企业业务快速增长,如新生产线的引入或外部公司的并购,这些活动往往伴随着新系统上线与独立数据体系的融入&a…

【safari】react在safari浏览器中,遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。如何解决

在safari浏览器中,可能会遇到异步时间差的问题,导致状态没有及时更新到state,引起传参错误。 PS:由于useState是一个普通的函数, 定义为() > void;因此此处不能用await/async替代setTimeout,只能用在返…

网络安全行业最大的敌人是自己

在危机四伏的数字丛林时代,网络安全行业需要跳出资本和市场的博弈陷阱,通过拯救自己来拯救所有人。当然,政府和资本也应该意识到这一点。 在当今这个数字化时代,网络安全的重要性与日俱增。然而,尽管政府和企业不断强调…

【vue+el-table】实现表尾合计行分两行显示,一行显示勾选项之和,一行显示合计,已实现,具体思路解析

效果图: 思路解析: 首先进行了el-table列表的组件封装,很多参数是传进来的。如果是普通的列表,相关参数直接定义就行 1、使用el-table的summary-method处理表尾行 (1)定义summaryIndex用于指定合计在哪一列…

vue学习笔记(十一)——开发心得(axios的封装、promise细节、vue-router开发中的使用)

1. axios的网络请求的封装 1.1 为什么要封装api? 代码分层,便于以后的修改,无需触碰逻辑页面 目标: 网络请求,不散落在各个逻辑页面里,封装起来方便以后修改 1.2 封装api步骤 ① 在项目 src 下新建目录 utlis &am…

VTD学习笔记(一)-启动vtd、基本界面和按钮

写在前面:真快啊,眨眼就毕业上班了,岗位也是做仿真,看来以后就是一直做仿真了,再见了定位~。公司使用的是vtd,看资料是一个很庞大的自动驾驶仿真软件,囊括了车辆动力学到传感器仿真,…

Python list comprehension (列表推导式 - 列表解析式 - 列表生成式)

Python list comprehension {列表推导式 - 列表解析式 - 列表生成式} 1. Python list comprehension (列表推导式 - 列表解析式 - 列表生成式)2. Example3. ExampleReferences Python 中的列表解析式并不是用来解决全新的问题,只是为解决已有问题提供新的语法。 列…

iPad型号数据解析:了解不同iPad型号的连接和扩展性能力

iPad是一款非常受欢迎的平板电脑,拥有多种型号和规格可供选择。在本篇文章中,我们将深入研究不同iPad型号的连接和扩展性能。数据源来自于挖数据平台,该平台提供了全面的iPad型号数据,共计1485个型号。 首先,让我们来…

【D3.js in Action 3 精译_020】2.6 用 D3 设置与修改元素样式 + 名人专访(Nadieh Bremer)+ 2.7 本章小结

当前内容所在位置 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可视化最佳实践(下)1.4 本章小结 第二章…

怎样用Java程序与数据库建立联系?

首先我们要了解一下JDBC,一个为Java程序与关系型数据库交互提供便利的API(应用程序编程接口), 本期我们尝试用Java编程软件IDEA与MYSQL数据库建立联系。 首先我们在IDEA中穿件一个(SQL),然后导…

系统编程--Linux下文件其他操作

这里写目录标题 文件存储理论补充dentry、inode 文件其他操作stat函数作用函数原型代码(以获取文件大小为例)补充(获取文件类型) lstat函数作用函数原型代码补充(获取文件权限)总结 tipslink函数作用简介函…

畅玩游戏新选择 :游戏本 Windows10 64位 专业版!

对于喜欢游戏竞技的玩家而言,选择一款合适的操作系统对于提升游戏体验至关重要。为了满足这一需求,系统之家小编将带来高性能的游戏本专用Win10操作系统。这一版本系统不仅注重游戏的稳定性,还针对玩家在游戏中可能遇到的超时检测和恢复&…

收银系统源码-千呼新零售收银视频介绍

千呼新零售2.0系统是零售行业连锁店一体化收银系统,包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体,线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

JavaScript 模板字符串:让字符串拼接变得更优雅

在 JavaScript 开发中,字符串拼接是一个常见的需求。从简单的用户界面文本生成到复杂的动态数据格式化,字符串操作无处不在。传统的字符串拼接方法虽然功能强大,但往往显得冗长且难以阅读。为了解决这一问题,ES6(ECMAS…

240718_使用Labelme制作自己的图像分割数据集

240718_使用Labelme制作自己的图像分割数据集 从目标检测入门的朋友们可能更熟悉的是LabelImg,这里要注意做好区分,LabelImg和Labelme不是一个东西,如下经典图: (a)图像分类(目标检测&#xff…

Mysql深入讲解(索引、事务、锁机制)

一、MySQL索引 1、何为索引? MySQL中的索引是一种数据结构,用于加快对数据库表中数据的查询速度【查询速度提升】。它类似于书本目录,使得用户可以根据特定字段快速定位到所需的数据行,而无需扫描整个表。 2、索引分类 Hash索…

怎样对 PostgreSQL 中的慢查询进行分析和优化?

🍅关注博主🎗️ 带你畅游技术世界,不错过每一次成长机会!📚领书:PostgreSQL 入门到精通.pdf 文章目录 怎样对 PostgreSQL 中的慢查询进行分析和优化?一、理解慢查询的危害二、找出慢查询&#x…

Linux可视化工具-netdata之docker安装

版本要求 docker cli安装 docker pull netdata/netdata docker run -d --namenetdata \ --pidhost \ --networkhost \ -v netdataconfig:/etc/netdata \ -v netdatalib:/var/lib/netdata \ -v netdatacache:/var/cache/netdata \ -v /:/host/root:ro,rslave \ -v /etc/passwd…

[集成学习]基于python的Stacking分类模型的客户购买意愿分类预测

1 导入必要的库 import pandas as pd import numpy as np import missingno as msno import matplotlib.pyplot as plt from matplotlib import rcParams import seaborn as sns from sklearn.metrics import roc_curve, auc from sklearn.linear_model import LogisticRegres…

业务架构、数据架构、应用架构和技术架构分析

一文看懂:什么是业务架构、数据架构、应用架构和技术架构 TOGAF(开放集团架构框架)是企业广泛应用的架构设计和管理利器。其核心在于四大架构领域:业务、数据、应用和技术,助力组织高效运作。TOGAF,让架构设…