冷血杀手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)
- 进程的内存大小,包括RSS,页表,swap使用。1KB计一分,root进程减去3%的分
- proc/PID/oom_score_adj 参数的分数加上。这个值默认是0,范围[-1000,1000]
- /proc/sys/vm/panic_on_oom 如果设置为1,那么oom killer启动的时候就会触发kernel panic。默认是0,咋一看设置为非0没啥用,但是kernel文档说的是集群中可以用来做failover,也可以设置为panic_on_oom=2+kdump,可以得到一个内核dump事后分析。
- /proc/sys/vm/oom_kill_allocating_task 设置为非0,则触发oom的进程会收到信号,不再对其他进程评分。默认是0。
- /proc/sys/vm/oom_dump_tasks 设置为非0,oom killer启动时就会输出进程列表,打印vm相关信息,rss,页表,swap使用,oom_score_adj,进程名字,pid,可以查看oom_killer选择的依据。默认是1。
- /proc/<PID>/oom_score_adj 评分的时候可以用来调整分数,负值可以减少评分,正值可以增加评分,取值-1000到1000,-1000可以完全禁止oom killer
- /proc/<PID>/oom_adj和/proc/<PID>/oom_score 兼容老的内核,oom_adj,取值从-16到15,-17可以禁止oom killer kill这个进程。oom_score显示oom killer评出来的分数。
程序员兵器之代码搜索工具
工欲善其事,必先利其器。对于程序员来说,除却编辑器,编译器这些引起N多纷争的神器不谈,代码搜索无疑是个很常见的事情,有个趁手的工具那自然是极好的。
说起这个话题,老前辈grep(wiki)自然必须要首先说一说,grep当仁不让的奉献了N多年,伴随Unix而生,更是在如今的*nix系统中必占一席之地。grep由Ken Thompson操刀写成,名字取自ed编辑器的g/re/p命令,自1973正式服役以来,赢得众多好评,为Unix-like系统的文本处理一大利器。grep功能强大在于支持regular expression(如果不知道regular expression为何物,作为一个程序员,你摊上事了,不过想要精通regular expression,你又摊上一个大事),模式匹配使用了Boyer-Moore算法,并且对Boyer-Moore算法做了相当的优化,有一个GNU grep为什么如此快的文章详细介绍了这一个(看这里)
事实上,作为每一个*nix系统必备的工具,有了grep和regex(regular expression简写),在搜索文本方面,几乎没多少困难了,更何况还有egrep(支持扩展的regex),zgrep(支持从压缩包匹配)等等更为强大的武装。而且掌握了这两大玩意,随便来一个*nix的系统,要从一堆文本中找出需要的东西应该都足够了。
但是,这么一个历史悠久,功能强大的工具也不能满足码农们日益增长的代码搜索需求,说大一点,正则表达式可以支撑绝大部分的文本匹配需求,但是复杂的正则表达式带来的是速度上的损耗,码农们日复一日的码代码,现在随便抓个代码库,都一大把的代码,更不要说像linux kernel这种重量级的codebase了,千万级的代码,想要找点什么东西不够快怎么行。快是一个方面,更好用也是一个很重要的方面,用户体验好,生产效率才高嘛。
有人的地方就有江湖,有程序员的地方就有需求。江湖路上没有永远的高手,昨日的高手是明日的英雄成名的基础。程序员为了能早点写完代码,去找找妹子,那自然要尽可能地追求各种效率,于是就有代表更强生产力的工具陆续出现在江湖。
首先出场,ack,掌声。。。
ack grep-like text finder(项目主页)
为什么要使用ack,它有什么优点呢?
ack用纯perl写成的脚本,这意味着任何支持perl的环境里都可以使用,安装方便,拷个文件就完事了。ack使用了高度优化的perl正则表达式,并且只搜索需要搜索的文件,略过那些备份文件,版本控制目录,而且支持只在一种语言的源文件中查找,而且输出结果更美观,比grep的要好看,还可以高亮搜索条目,重要的一点是,ack的参数和grep差不多,习惯grep的人能无缝切换到ack。噢,还有一点,ack打起来比grep快,哈哈。官方列出的why ack
ack能忽略版本控制目录或者只搜索一种语言的源文件很好用,试比较一下这两个场景
在一个svn版本库中搜索代码
$ grep pattern $(find . -type f | grep -v '\.svn')
$ ack pattern
只搜索perl源码文件
$ grep pattern $(find . -name '*.pl' -or -name '*.pm' -or -name '*.pod' | grep -v .svn)
$ ack --perl pattern
比grep命令要节省时间,而且结果还更美观。
安装ack超级简单,有standalone版本(http://betterthangrep.com/ack-standalone),也可以使用发行版的包管理工具来搜索,或者参见这里(http://betterthangrep.com/install/)
ack是很强大(还有传说中的ack 2.0在开发中),但是江山代有才人出,一山更比一山高。一般情况下“但是”这个中国词一出,前面的都要悲剧。下一位选手the silver searcher更是力压ack大胜grep。
the silver searcher(后面简称ag,因为命令行是ag,哈哈,ag又比ack要好打),项目主页(https://github.com/ggreer/the_silver_searcher)
ag的介绍语是
The Silver Searcher
An attempt to make something better than ack
(which itself is better than grep
).
据说比ack能快上3-5倍,还可以自定义忽略对象,而且,命令比ack要短33%,lol
为什么快?
1. 明文字符串使用Boyer-Moore-Horspool算法
2. 使用mmap
3. 多线程
4. ……
具体可以参见:https://github.com/ggreer/the_silver_searcher/blob/master/README.md
ag是用C写的,需要pcre库的支持,源码可以从github的仓库获得。
这些都是说的,是骡子是马,还要拉出来溜溜才行,下面以kernel-3.6.11代码为例,来试试这几大武器。
$ time grep -r out_of_memory *
real 1m10.134s
user 0m0.153s
sys 0m8.576s
$ time grep out_of_memory $(find . -type f | grep -v '\.git')
real 1m15.837s
user 0m0.557s
sys 0m9.379s
$ time ack out_of_memory
real 1m18.256s
user 0m4.870s
sys 0m12.683s
$ time ag out_of_memory
real 0m49.022s
user 0m0.550s
sys 0m10.309s
大致看一下,ack其实和grep差不多的,甚至grep还快一点,ack的优点就是使用方便,输出更直观,但是ag就是实打实的快很多了。so,the winner is ag。
PS:根据ag作者介绍,还有个git-grep,速度和ag差不多,但是只能在git仓库里面用。
update:更多类似工具,参见这里:http://betterthangrep.com/more-tools/
Tcpdump抓包重放
开发工作中经常有这样的场景,和同事联调的时候,对方发了一个测试包过来,这边用tcpdump –Xlnsp0抓到包了,但是程序结果不正确,然后自己debug,修改,然后需要再测试,这时候再让同事发一个?如果不正确,这一来一回的比较慢,如果有个工具自动把tcpdump抓下来的内容再发出去,就ok了。
于是问题就是这样的,比如用tcpdump –Xlnps0抓到一个udp包,然后用工具把这个包重新发出去。
![endif]--> !--[if> ![endif]--> !--[if> ![endif]--> !--[if> ![endif]--> !--[if>
打造ArchLinux下的类apt-get source工具
首先广告一下,Arch Linux 是我用过的最喜欢的一个Linux发行版,它是一个滚动升级模式的i686/x86-64 Linux发行版,它的开发注重于系设计简洁、结构优雅、代码 准确、体验新潮的完美权衡。它给你一个最小的系统,但是提供很强大的包管理,从而你可以自由的构建一个理想的系统,它的包管理强大之处在于它有两套包管理系统,一个是基于pacman的二进制包管理系统,类似ubuntu下的apt-get 系统,使用官方仓库,提供大量打包好的软件包可供直接使用,另外一个就是全功能的类ports的ABS(Arch Build System)软件包管理系统,类似gentoo的emerge系统,可以很方便的从源码构建软件,而且构建出来的软件也纳入pacman的包管理系统,这样就可以方便的缷载软件,避免了最普通的configure&&make&&make install这一种从源码构建方式不易缷载的问题。ABS实际上维护了一个PKGBUILD文件集合,其中每个PKGBUILD文件对应一个软件,可以使用makepkg命令来通过PKGBUILD构建软件。ABS其中的软件包是社区维护用户的,任何人都可以提交可以构建软件的PKGBUILD,从而形成了一个非常巨大的仓库,这个仓库就叫AUR(Arch Linux User-community Repository)。
计算两个日期的差值
记得今年早些时候看到百度员工出的那个视频,中间有一幕女主角在计算自己自出生以来已经生活了多少天,只见她熟练的打开excel,在A1中输入生日,在B1中输入当天日期,在C1中输入=B1-A1,立刻得到自己来到这个世上的时间,眼看过去了这么多天,自己当初的梦想实现了多少呢,……,剧情自此展开,不再追踪。
我看到这个的时候,想着cli控们有没有什么方法能实现同样的功能呢,无所不能的shell(我记得有人说过shell是完备的)啊,需要你的力量。
想了一下,使用了coreutils中的date命令,写成了如下shell脚本: