温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何理解case的排查过程

发布时间:2021-10-25 16:18:56 阅读:360 作者:iii 栏目:编程语言
开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止! 点击查看>>

这篇文章主要介绍“如何理解case的排查过程”,在日常操作中,相信很多人在如何理解case的排查过程问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何理解case的排查过程”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

具体过程

如何理解case的排查过程

申请4g内存失败

如上图所示,记录显示为申请 4G 内存失败(4294967296 B / 1024 / 1024 = 4096 M)。

是否是 min_free_kbytes & nr_hugepage 配置错误?

  1. 第一反应是想起来之前的  vm.min_free_kbytes & nr_hugepage 导致的free大于available案例有关

memfree 统计的是所有内存的 free 内存,而 memavailable 统计的是可以拿来给程序用的内存,而客户设置了 vm.min_free_kbytes(2.5G),这个内存在 free 统计,但是不在 memavailable 统计,nr_hugepage 也会有这个问题。

二者的统计方式不一样, 具体参考 Documentation/filesystems/proc.txt

  • MemFree: The sum of LowFree+HighFree
  • MemAvailable: An estimate of how much memory is available for starting new applications, without swapping. Calculated from MemFree, SReclaimable, the size of the file LRU lists, and the low watermarks in each zone. The estimate takes into account that the system needs some page cache to function well, and that not all reclaimable slab will be reclaimable, due to items being in use. The impact of those factors will vary from system to system.
  1. 跟客户要  free -m && sysctl -p && /proc/meminfo 等信息分析问题。
  • HugePages_Total 为0,说明没有设置  nr_hugepage
  • MemAvailable: 7418172 kB, 说明这么多内存可用。
# sysctl -pnet.ipv4.ip_forward = 0net.ipv4.conf.default.accept_source_route = 0kernel.sysrq = 1kernel.core_uses_pid = 1net.ipv4.tcp_syncookies = 1...net.ipv4.tcp_tw_recycle=1net.ipv4.tcp_max_syn_backlog=4096net.core.netdev_max_backlog=10000vm.overcommit_memory=2...
#cat /proc/meminfoMemTotal:        8009416 kBMemFree:         7347684 kBMemAvailable:    7418172 kBBuffers:           18924 kBCached:           262836 kBSwapCached:            0 kBActive:           315188 kBInactive:         222364 kBActive(anon):     256120 kBInactive(anon):      552 kBActive(file):      59068 kBInactive(file):   221812 kB....HugePages_Total:       0  HugePages_Free:        0HugePages_Rsvd:        0HugePages_Surp:        0Hugepagesize:       2048 kBDirectMap4k:      114560 kBDirectMap2M:     4079616 kBDirectMap1G:     6291456 kB

尝试重现

  1. 尝试自行测试使用 java命令,去申请超出我的测试机物理内存,拿到报错。

实际上面的meminfo已经说明了问题,但是由于经验不足,一时没有看明白怎么回事。

下面测试证明正常申请内存不会有问题,超额的内存才会 OOM。

[root@test ~]# java -Xms4096M -versionopenjdk version "1.8.0_242"OpenJDK Runtime Environment (build 1.8.0_242-b08)OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)[root@test ~]# java -Xms5000M -versionOpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000687800000, 3495428096, 0) failed; error='Cannot allocate memory' (errno=12)......

系统信息如下:

---------------  S Y S T E M  ---------------OS:CentOS Linux release 7.4.1708 (Core)uname:Linux 3.10.0-693.2.2.el7.x86_64 #1 SMP Tue Sep 12 22:26:13 UTC 2017 x86_64libc:glibc 2.17 NPTL 2.17rlimit: STACK 8192k, CORE 0k, NPROC 15088, NOFILE 65535AS infinityload average:0.05 0.05 0.05/proc/meminfo:MemTotal:        3881692 kBMemFree:         2567724 kBMemAvailable:    2968640 kBBuffers:           69016 kBCached:           536116 kBSwapCached:            0 kBActive:           355280 kBInactive:         326020 kB...VmallocTotal:   34359738367 kBVmallocUsed:       14280 kBVmallocChunk:   34359715580 kBHardwareCorrupted:     0 kBAnonHugePages:     30720 kBHugePages_Total:     256HugePages_Free:      256HugePages_Rsvd:        0HugePages_Surp:        0Hugepagesize:       2048 kBDirectMap4k:       57216 kBDirectMap2M:     3088384 kBDirectMap1G:     3145728 kB....Memory: 4k page, physical 3881692k(2567600k free), swap 0k(0k free)vm_info: OpenJDK 64-Bit Server VM (25.242-b08) for linux-amd64 JRE (1.8.0_242-b08), built on Jan 28 2020 14:28:22 by "mockbuild" with gcc 4.8.5 20150623 (Red Hat 4.8.5-39)time: Thu Feb 20 15:13:30 2020timezone: CSTelapsed time: 0 seconds (0000s)

重现失败,继续分析

  1. Java 测试证明正常申请内存不会有问题,超额的内存才会 OOM,那么为什么超额呢,视线回归到  sysctl -p 有所发现。

vm.overcommit_memory=2

关于 overcommit_memory 设置项:

overcommit_memory=0

默认设置,当应用进程尝试申请内存时,内核会做一个检测。内核将检查是否有足够的可用内存供应用进程使用;

如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。

举个例子,比如1G的机器,A进程已经使用了500M,当有另外进程尝试malloc 500M的内存时,内核就会进行check,发现超出剩余可用内存,就会提示失败。

overcommit_memory=1

对于内存的申请请求,内核不会做任何check,直到物理内存用完,触发 OOM 杀用户态进程。

同样是上面的例子,1G 的机器,A进程500M,B进程尝试 malloc 500M,会成功,但是一旦kernel发现内存使用率接近1个G(内核有策略),就触发OOM,杀掉一些用户态的进程(有策略的杀)。

overcommit_memory=2

当请求申请的内存 >= SWAP内存大小 + 物理内存 * N,则拒绝此次内存申请。解释下这个N:N是一个百分比,根据overcommit_ratio/100来确定,比如overcommit_ratio=50(我的测试机默认50%),那么N就是50%。 vm.overcommit_ratio 只有当 vm.overcommit_memory = 2 的时候才会生效,内存可申请内存为 SWAP内存大小 + 物理内存 * overcommit_ratio/100

看看上面日志的 overcommit 信息:

  • CommitLimit: 4004708 kB (小于客户申请的4096M)
  • Committed_AS: 2061568 kB

具体而言:

  • CommitLimit:最大能分配的内存(测试下来在 vm.overcommit_memory=2时候生效),具体的值是:SWAP内存大小(ecs均未开启) + 物理内存 * overcommit_ratio / 100;
  • Committed_AS:当前已经分配的内存大小;

5,两相对照,说明客户设置的 vm.overcommit_memory在生效,建议改回 0 再试试。

  • 用  vm.overcommit_memory = 2 测试,分配内存失败;
[root@test ~]# grep -i commit /proc/meminfoCommitLimit:     1940844 kBCommitted_AS:     480352 kB# java -Xms2048M -version 失败了OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x000000008000000014318305280) failed; error='Cannot allocate memory' (errno=12)## There is insufficient memory for the Java Runtime Environment to continue.# Native memory allocation (mmap) failed to map 1431830528 bytes for committing reserved memory.# An error report file with more information is saved as:# /root/hs_err_pid1267.log
  • 用如下配置,即可恢复:  vm.overcommit_memory = 0, vm.overcommit_ratio = 50
#vm.overcommit_memory = 0#vm.overcommit_ratio = 50[root@test ~]# java -Xms2048M -versionopenjdk version "1.8.0_242"OpenJDK Runtime Environment (build 1.8.0_242-b08)OpenJDK 64-Bit Server VM (build 25.242-b08, mixed mode)

到此,关于“如何理解case的排查过程”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

原文链接:https://my.oschina.net/u/4599303/blog/4699240

AI

开发者交流群×