如何理解case的排查过程

发布时间:2021-10-25 16:18:56 作者:iii
来源:亿速云 阅读:350

这篇文章主要介绍“如何理解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

  1. 跟客户要  free -m && sysctl -p && /proc/meminfo 等信息分析问题。
# sysctl -p
net.ipv4.ip_forward = 0
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 1
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
...
net.ipv4.tcp_tw_recycle=1
net.ipv4.tcp_max_syn_backlog=4096
net.core.netdev_max_backlog=10000
vm.overcommit_memory=2
...
#cat /proc/meminfo
MemTotal:        8009416 kB
MemFree:         7347684 kB
MemAvailable:    7418172 kB
Buffers:           18924 kB
Cached:           262836 kB
SwapCached:            0 kB
Active:           315188 kB
Inactive:         222364 kB
Active(anon):     256120 kB
Inactive(anon):      552 kB
Active(file):      59068 kB
Inactive(file):   221812 kB
....
HugePages_Total:       0  
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      114560 kB
DirectMap2M:     4079616 kB
DirectMap1G:     6291456 kB

尝试重现

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

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

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

[root@test ~]# java -Xms4096M -version
openjdk 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 -version
OpenJDK 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_64
libc:glibc 2.17 NPTL 2.17
rlimit: STACK 8192k, CORE 0k, NPROC 15088, NOFILE 65535, AS infinity
load average:0.05 0.05 0.05
/proc/meminfo:
MemTotal:        3881692 kB
MemFree:         2567724 kB
MemAvailable:    2968640 kB
Buffers:           69016 kB
Cached:           536116 kB
SwapCached:            0 kB
Active:           355280 kB
Inactive:         326020 kB
...
VmallocTotal:   34359738367 kB
VmallocUsed:       14280 kB
VmallocChunk:   34359715580 kB
HardwareCorrupted:     0 kB
AnonHugePages:     30720 kB
HugePages_Total:     256
HugePages_Free:      256
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       57216 kB
DirectMap2M:     3088384 kB
DirectMap1G:     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 2020
timezone: CST
elapsed time: 0 seconds (0d 0h 0m 0s)

重现失败,继续分析

  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 信息:

具体而言:

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

[root@test ~]# grep -i commit /proc/meminfo
CommitLimit:     1940844 kB
Committed_AS:     480352 kB
# java -Xms2048M -version 失败了
OpenJDK 64-Bit Server VM warning: INFO: os::commit_memory(0x0000000080000000, 1431830528, 0) 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
[root@test ~]# java -Xms2048M -version
openjdk 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的排查过程”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. MySQL 存储过程CASE语句用法
  2. 如何分析磁盘IO高的问题排查过程

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

linux java

上一篇:Mysql如何使用Maxscale中间件

下一篇:MySQL参数调优的最佳实践是怎么样的

相关阅读

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

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