{"id":18,"date":"2007-09-02T02:32:50","date_gmt":"2007-09-01T23:32:50","guid":{"rendered":"http:\/\/www.held.org.il\/blog\/?p=18"},"modified":"2007-09-02T02:32:50","modified_gmt":"2007-09-01T23:32:50","slug":"out-of-memory-in-linux-or-oom-killer","status":"publish","type":"post","link":"http:\/\/www.held.org.il\/blog\/2007\/09\/out-of-memory-in-linux-or-oom-killer\/","title":{"rendered":"Out of memory in Linux (or: OOM Killer)"},"content":{"rendered":"<p>Do you remember DOS games or apps quitting with the reason 'not enough memory'? It rarely happens today, because physical ram is not the limit - physical ram + swap, or <strong>virtual memory size<\/strong> is the limit.<\/p>\n<p>So what happens when we're out of virtual memory?  Linux doesn't crash. Instead, it looks for the best process(es) to kill. \"Best\" means: killing the process will free up lots of memory, but will do the least damage possible (i.e. don't kill init, hardware-bound process, or a long-running software).<\/p>\n<p><!--more--><\/p>\n<h3>Who do you want to assassinate today? (tm)<\/h3>\n<p>The relevant part in the kernel is called <strong>OOM Killer<\/strong> , written by <a href=\"http:\/\/surriel.com\/\">Rik Van-Riel<\/a>, a Linux memory management guru.<\/p>\n<p>OOM Killer gives score to each process, which can be seen in <em>\/proc\/&lt;pid&gt;\/oom_score<\/em>. Higher score means better candidate for killing. The scoring algorithm as of 2.6.22, follows (Please comment if something here is not correct):<\/p>\n<ol>\n<li>Take the <strong>number of bytes of virtual memory<\/strong> the process uses, plus <strong>half of the bytes of the children<\/strong>.<\/li>\n<li><strong>Divide<\/strong> by sqrt(<strong>cpu time seconds<\/strong>)<\/li>\n<li><strong>Divide<\/strong> by sqrt(<strong>run time seconds<\/strong> - time since the program started)<\/li>\n<li><strong>Multiply<\/strong> by two, if process is nice (nice&gt;0)<\/li>\n<li><strong>Divide<\/strong> by four if it's owned by <strong>root<\/strong><\/li>\n<li><strong>Divide<\/strong> by four if it's accessing <strong>hardware<\/strong><\/li>\n<li><strong>Divide<\/strong> by eight if the process' memory does not overlap &lt;- I'm not sure about that, I think it's SMP-related.<\/li>\n<li><strong>Shift<\/strong> by <strong>oomkilladj<\/strong> (explanation follows)<\/li>\n<\/ol>\n<h3>Adjusting the killer's scoring systems<\/h3>\n<p>And to the cool part: <strong>oomkilladj<\/strong> is a way to adjust the process' score! <em>\/proc\/&lt;pid&gt;\/oom_adj<\/em> is zero by default, but can be -17 to 15. You can play with it and see <em>oom_score<\/em> changes immediately!<\/p>\n<p>The value '2' would shift-left the score twice (multiply by four), while the value '-1' would shift-right the score once (divide by two).<\/p>\n<p>-17 is a special value meaning <strong>never kill <\/strong>this process.<\/p>\n<h3>Seeing it live..<\/h3>\n<p>And just to make this post complete, here's a little script which prints the list of processes and their oom_score, ordered by oom_score ascending:<\/p>\n<pre>#!\/bin\/bash\nfor i in `find \/proc -maxdepth 1 -type d`; do\nif [ -f $i\/oom_score ]; then\necho -n \"$i \";\ncat $i\/oom_score;\nfi;\ndone | sort -n -k2<\/pre>\n<h3>Refs<\/h3>\n<ul>\n<li>linux-source\/mm\/oom_kill.c<\/li>\n<li><a href=\"http:\/\/linux-mm.org\/OOM_Killer\">From linux-mm.org<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Do you remember DOS games or apps quitting with the reason &#8216;not enough memory&#8217;? It rarely happens today, because physical ram is not the limit &#8211; physical ram + swap, or virtual memory size is the limit. So what happens when we&#8217;re out of virtual memory? Linux doesn&#8217;t crash. Instead, it looks for the best [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[75],"tags":[70,203],"_links":{"self":[{"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/posts\/18"}],"collection":[{"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/comments?post=18"}],"version-history":[{"count":0,"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/posts\/18\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/media?parent=18"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/categories?post=18"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.held.org.il\/blog\/wp-json\/wp\/v2\/tags?post=18"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}