Crane
Table_bottom

Search
Loading
Table_bottom

分类
Table_bottom

随机文章
Table_bottom

标签云
Table_bottom

最新评论
Table_bottom

链接
Table_bottom

功能
Table_bottom

冷血杀手OOM_Killer

Crane posted @ 2013年3月24日 02:22 in Linux with tags linux , 8796 阅读

 

前几天在折腾systemtap,其实我没想折腾来着,我就是想装个玩玩而已。需要有debug_info的内核,没问题啊,archlinux下这个easy,我从abs拉一个linux的PKGBUILD来改一下配置,按说立马就能make一个出来,我的linux实机上也确实没问题,一下子就出来一个,再装上systemtap,试两个命令,一切工作正常。但是我还有个windows下的虚拟机,有时在win下活动的时候偶尔也用用,就是在这货上装的时候出了问题,当开始编译的时候,我就关上屏幕睡觉去了,一觉起来,却发现没打好包,屏幕上提示什么链接vmlinuz的那个脚本报错,怪了,这脚本能有bug才怪。但是在公司的电脑上虚拟机却没问题,比了下是虚拟机设置的内存大小不一样,出问题的这个内存太小,于是我就去系统日志看了下,发现有句日志报了oom_killer启动把ld给杀掉了,我屮,就说链接的脚本报错,ld还没链完,就被干掉了,当然没结果了。知道问题就好办了,多开点swap让它干活去呗,也就啥事都没有了。
 
这个oom_killer就是Out Of Memory Killer,当系统的内存和交换区用尽的时候,系统为了保证可用性,会挑选出进程kill掉,为了证明是系统有意地行为,不是系统不稳定,不是系统bug,oom_killer会在干掉进程后,在系统日志里留下记录,大有此货是我杀,你能奈我何的风范。
 
一般系统日志中的输出类似这样(我当时的没留下来,从网上搜了一个)
python invoked oom-killer: gfp_mask=0x1200d2, order=0, oomkilladj=4
Pid: 13996, comm: python Not tainted 2.6.27-gentoo-r8cluster-e1000 #9

Call Trace:
 [<ffffffff8025ab6b>] oom_kill_process+0x57/0x1dc
 [<ffffffff802460c7>] getnstimeofday+0x53/0xb3
 [<ffffffff8025ae78>] badness+0x16a/0x1a9
 [<ffffffff8025b0a9>] out_of_memory+0x1f2/0x25c
 [<ffffffff8025e181>] __alloc_pages_internal+0x30f/0x3b2
 [<ffffffff8026fea0>] read_swap_cache_async+0x48/0xc0
 [<ffffffff8026ff6f>] swapin_readahead+0x57/0x98
 [<ffffffff80266d0e>] handle_mm_fault+0x408/0x706
 [<ffffffff8057da33>] do_page_fault+0x42c/0x7e7
 [<ffffffff8057baf9>] error_exit+0x0/0x51

Mem-Info:
Node 0 DMA per-cpu:
CPU    0: hi:    0, btch:   1 usd:   0
CPU    1: hi:    0, btch:   1 usd:   0
CPU    2: hi:    0, btch:   1 usd:   0
CPU    3: hi:    0, btch:   1 usd:   0
Node 0 DMA32 per-cpu:
CPU    0: hi:  186, btch:  31 usd: 103
CPU    1: hi:  186, btch:  31 usd:  48
CPU    2: hi:  186, btch:  31 usd: 136
CPU    3: hi:  186, btch:  31 usd: 183
Active:480346 inactive:483 dirty:0 writeback:10 unstable:0
 free:3408 slab:5146 mapped:1408 pagetables:2687 bounce:0
Node 0 DMA free:8024kB min:20kB low:24kB high:28kB active:1156kB inactive:0kB present:8364kB pages_scanned:3246 all_unreclaimable? yes
lowmem_reserve[]: 0 2003 2003 2003
Node 0 DMA32 free:5608kB min:5716kB low:7144kB high:8572kB active:1920228kB inactive:1932kB present:2051308kB pages_scanned:2941301 all_unreclaimable? yes
lowmem_reserve[]: 0 0 0 0
Node 0 DMA: 8*4kB 3*8kB 4*16kB 3*32kB 4*64kB 3*128kB 2*256kB 3*512kB 3*1024kB 1*2048kB 0*4096kB = 8024kB
Node 0 DMA32: 42*4kB 6*8kB 1*16kB 0*32kB 2*64kB 1*128kB 0*256kB 0*512kB 1*1024kB 0*2048kB 1*4096kB = 5608kB
325424 total pagecache pages
323900 pages in swap cache
Swap cache stats: add 20776604, delete 20452704, find 7856195/10744535
Free swap  = 151691424kB
Total swap = 156290896kB
524032 pages RAM
9003 pages reserved
331431 pages shared
186210 pages non-shared
Out of memory: kill process 12965 (bash) score 2236480 or a child
Killed process 13996 (python)
 
如果出现了这样的日志,就证明oom_killer已经干活完毕,不知哪个倒霉鬼进程已经挂在它手下了。要是生产环境中碰到这样的事情,生产进程被干掉了,就危险了,因此研究oom_killer挑选目标的方法也许就能帮助特别重要的进程逃过一劫。
 
当内存耗尽的时候,会触发oom_killer出来干活,oom_killer会遍历所有进程,并给每个进程打分,这里得分可不是什么好事,oom_killer扫完所有进程后会把得分最高的那个进程干掉。
 
oom_killer的评分会考虑很多因素,主要有这么几个方面(linux 3.7.10-1 mm/oom_kill.c),最低分0,最高1000.
  1. 进程的内存大小,包括RSS,页表,swap使用。1KB计一分,root进程减去3%的分
  2. proc/PID/oom_score_adj 参数的分数加上。这个值默认是0,范围[-1000,1000]
以前貌似评价标准有好多,现在只有简单的判断内存使用和sysctl参数了。比如这里的资料,评分标准就比较多:http://linux-mm.org/OOM_Killer
 
proc中有几个参数与oom killer有关系
  1. /proc/sys/vm/panic_on_oom 如果设置为1,那么oom killer启动的时候就会触发kernel panic。默认是0,咋一看设置为非0没啥用,但是kernel文档说的是集群中可以用来做failover,也可以设置为panic_on_oom=2+kdump,可以得到一个内核dump事后分析。
  2. /proc/sys/vm/oom_kill_allocating_task 设置为非0,则触发oom的进程会收到信号,不再对其他进程评分。默认是0。
  3. /proc/sys/vm/oom_dump_tasks 设置为非0,oom killer启动时就会输出进程列表,打印vm相关信息,rss,页表,swap使用,oom_score_adj,进程名字,pid,可以查看oom_killer选择的依据。默认是1。
  4. /proc/<PID>/oom_score_adj 评分的时候可以用来调整分数,负值可以减少评分,正值可以增加评分,取值-1000到1000,-1000可以完全禁止oom killer
  5. /proc/<PID>/oom_adj和/proc/<PID>/oom_score 兼容老的内核,oom_adj,取值从-16到15,-17可以禁止oom killer kill这个进程。oom_score显示oom killer评出来的分数。
Avatar_small
依云 说:
2013年3月24日 03:12

Arch 内核开 debug_info 就好大好大的= =


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter