記redis程序oom的排查過(guò)程

釘釘群收到告警爆袍,redis服務(wù)兩個(gè)掛了艇肴。登錄服務(wù)器通過(guò)dmesg命令查看進(jìn)程掛掉原因哄酝,看到以下日志

[21367253.038320] Node 0 DMA free:15908kB min:8kB low:8kB high:12kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
[21367253.046752] lowmem_reserve[]: 0 2825 96503 96503
[21367253.048506] Node 0 DMA32 free:376572kB min:1976kB low:2468kB high:2964kB active_anon:2441228kB inactive_anon:16kB active_file:12kB inactive_file:16kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:3129212kB managed:2893660kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:16kB slab_reclaimable:49568kB slab_unreclaimable:2944kB kernel_stack:448kB pagetables:16104kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:8 all_unreclaimable? no
[21367253.057509] lowmem_reserve[]: 0 0 93677 93677
[21367253.059225] Node 0 Normal free:85808kB min:65592kB low:81988kB high:98388kB active_anon:94857072kB inactive_anon:256kB active_file:3492kB inactive_file:3120kB unevictable:0kB isolated(anon):0kB isolated(file):128kB present:97517568kB managed:95925820kB mlocked:0kB dirty:0kB writeback:0kB mapped:996kB shmem:620kB slab_reclaimable:72616kB slab_unreclaimable:35820kB kernel_stack:4752kB pagetables:227860kB unstable:0kB bounce:0kB free_pcp:2560kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:9970 all_unreclaimable? yes
[21367253.069788] lowmem_reserve[]: 0 0 0 0
[21367253.071491] Node 0 DMA: 1*4kB (U) 0*8kB 0*16kB 1*32kB (U) 2*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (M) 3*4096kB (M) = 15908kB
[21367253.075622] Node 0 DMA32: 2355*4kB (UEM) 2103*8kB (UEM) 584*16kB (UEM) 293*32kB (UEM) 131*64kB (UEM) 5*128kB (EM) 58*256kB (UM) 275*512kB (UM) 163*1024kB (M) 0*2048kB 0*4096kB = 376548kB
[21367253.080198] Node 0 Normal: 21012*4kB (UEM) 251*8kB (UEM) 21*16kB (EM) 2*32kB (EM) 1*64kB (M) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 86520kB
[21367253.084547] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB
[21367253.086812] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[21367253.089058] 2129 total pagecache pages
[21367253.090883] 0 pages in swap cache
[21367253.092648] Swap cache stats: add 0, delete 0, find 0/0
[21367253.094588] Free swap  = 0kB
[21367253.096303] Total swap = 0kB
[21367253.098010] 25165693 pages RAM
[21367253.099735] 0 pages HighMem/MovableOnly
[21367253.101522] 456846 pages reserved

[21367253.103259] [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
[21367253.105522] [ 3086]     0  3086    20024       87      45        0             0 systemd-journal
[21367253.107824] [ 5969]     0  5969     6718      217      18        0             0 systemd-logind
[21367253.110105] [ 5970]    81  5970    14564      179      31        0          -900 dbus-daemon
[21367253.112372] [ 5983]     0  5983   615231    10802      91        0             0 CmsGoAgent.linu
[21367253.114683] [ 6054]     0  6054    27523       33      11        0             0 agetty
[21367253.116926] [ 6058]     0  6058    27523       33      11        0             0 agetty
[21367253.119135] [ 6316]     0  6316    26839      498      51        0             0 dhclient
[21367253.121366] [ 7035]     0  7035   138962     1919      39        0             0 ops-updater
[21367253.123756] [ 7079]     0  7079   589598     6289      85        0             0 falcon-agent
[21367253.126011] [13594]  1000 13594 11667269  6644047   19394        0             0 redis-server
[21367253.128270] [13599]  1000 13599  8243013  6664731   15518        0             0 redis-server
[21367253.130502] [15685]  1000 15685  6917957  5449843   13398        0             0 redis-server
[21367253.132724] [15693]  1000 15693  5857093  5411665   11080        0             0 redis-server
[21367253.134943] [32218]  1000 32218   127813    52828     152        0             0 redis-server
[21367253.137165] [32223]  1000 32223   113477    56705     139        0             0 redis-server
[21367253.139349] [32736]  1000 32736    28295       67      13        0             0 sh
[21367253.141429] [20078]     0 20078    78343     3993     104        0             0 salt-minion
[21367253.143574] [20083]     0 20083   237123    11662     163        0             0 salt-minion
[21367253.145663] [20087]     0 20087   103223     6598     113        0             0 salt-minion
[21367253.147739] [14046]     0 14046    10494      216      13        0             0 aliyun-service
[21367253.149802] [ 3366]     0  3366   109273      676      28        0             0 AliHips
[21367253.151773] [ 9827]     0  9827     6614      359      18        0             0 AliYunDunUpdate
[21367253.153774] [ 9944]     0  9944    32536     1953      59        0             0 AliYunDun
[21367253.155691] [  340]     0   340    28230      258      57        0         -1000 sshd
[21367253.157612] [  483]    28   483   148240      135      43        0             0 nscd
[21367253.159441] [  557]     0   557    13882      112      26        0         -1000 auditd
[21367253.161233] [  691]   998   691    24120       95      18        0             0 chronyd
[21367253.163013] [  729]     0   729    31573      157      18        0             0 crond
[21367253.164794] [  814]   999   814   153061     2128      63        0             0 polkitd
[21367253.166505] [28544]     0 28544    11152      105      23        0         -1000 systemd-udevd
[21367253.168272] [28629]     0 28629   160279      185     142        0             0 rsyslogd
[21367253.169980] Out of memory: Kill process 13599 (redis-server) score 270 or sacrifice child
[21367253.171663] Killed process 13599 (redis-server) total-vm:32972052kB, anon-rss:26658828kB, file-rss:88kB, shmem-rss:0kB

日志內(nèi)容顯示 Out of memory: Kill process 13599 (redis-server)麦向,所以是由于內(nèi)存不足瓢棒,被系統(tǒng)給結(jié)束了進(jìn)程浴韭。

原因分析

1). redis-server進(jìn)程觸發(fā)了oom killer,既redis要申請(qǐng)的內(nèi)存大于了系統(tǒng)可用的物理內(nèi)存大小脯宿。/proc/sys/vm/min_free_kbytes 參數(shù)來(lái)控制念颈,當(dāng)系統(tǒng)可用內(nèi)存(不包含buffer和cache)小于這個(gè)值的時(shí)候,系統(tǒng)會(huì)啟動(dòng)內(nèi)核線程kswapd來(lái)對(duì)內(nèi)存進(jìn)行回收连霉。而還是觸發(fā)了oom killer榴芳,則表明內(nèi)存真的不夠用了或者在內(nèi)存回收前或者回收中直接觸發(fā)了oom killer。

2). 如下的輸出表明了申請(qǐng)了3次內(nèi)存都沒(méi)有成功

[21367253.038320] Node 0 DMA free:15908kB min:8kB low:8kB high:12kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
[21367253.046752] lowmem_reserve[]: 0 2825 96503 96503
[21367253.048506] Node 0 DMA32 free:376572kB min:1976kB low:2468kB high:2964kB active_anon:2441228kB inactive_anon:16kB active_file:12kB inactive_file:16kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:3129212kB managed:2893660kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:16kB slab_reclaimable:49568kB slab_unreclaimable:2944kB kernel_stack:448kB pagetables:16104kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:8 all_unreclaimable? no
[21367253.057509] lowmem_reserve[]: 0 0 93677 93677
[21367253.059225] Node 0 Normal free:85808kB min:65592kB low:81988kB high:98388kB active_anon:94857072kB inactive_anon:256kB active_file:3492kB inactive_file:3120kB unevictable:0kB isolated(anon):0kB isolated(file):128kB present:97517568kB managed:95925820kB mlocked:0kB dirty:0kB writeback:0kB mapped:996kB shmem:620kB slab_reclaimable:72616kB slab_unreclaimable:35820kB kernel_stack:4752kB pagetables:227860kB unstable:0kB bounce:0kB free_pcp:2560kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:9970 all_unreclaimable? yes
[21367253.069788] lowmem_reserve[]: 0 0 0 0
[21367253.071491] Node 0 DMA: 1*4kB (U) 0*8kB 0*16kB 1*32kB (U) 2*64kB (U) 1*128kB (U) 1*256kB (U) 0*512kB 1*1024kB (U) 1*2048kB (M) 3*4096kB (M) = 15908kB
[21367253.075622] Node 0 DMA32: 2355*4kB (UEM) 2103*8kB (UEM) 584*16kB (UEM) 293*32kB (UEM) 131*64kB (UEM) 5*128kB (EM) 58*256kB (UM) 275*512kB (UM) 163*1024kB (M) 0*2048kB 0*4096kB = 376548kB
[21367253.080198] Node 0 Normal: 21012*4kB (UEM) 251*8kB (UEM) 21*16kB (EM) 2*32kB (EM) 1*64kB (M) 0*128kB 0*256kB 0*512kB 0*1024kB 0*2048kB 0*4096kB = 86520kB
[21367253.084547] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB
[21367253.086812] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[21367253.089058] 2129 total pagecache pages
[21367253.090883] 0 pages in swap cache
[21367253.092648] Swap cache stats: add 0, delete 0, find 0/0
[21367253.094588] Free swap  = 0kB
[21367253.096303] Total swap = 0kB
[21367253.098010] 25165693 pages RAM
[21367253.099735] 0 pages HighMem/MovableOnly
[21367253.101522] 456846 pages reserved

各個(gè)zone的情況如何跺撼?

[21367253.038320] Node 0 DMA free:15908kB min:8kB low:8kB high:12kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:15992kB managed:15908kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
lowmem_reserve[]: 0 2825 96503 96503

[21367253.048506] Node 0 DMA32 free:376572kB min:1976kB low:2468kB high:2964kB active_anon:2441228kB inactive_anon:16kB active_file:12kB inactive_file:16kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:3129212kB managed:2893660kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:16kB slab_reclaimable:49568kB slab_unreclaimable:2944kB kernel_stack:448kB pagetables:16104kB unstable:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:8 all_unreclaimable? no
lowmem_reserve[]: 0 0 93677 93677

[21367253.059225] Node 0 Normal free:85808kB min:65592kB low:81988kB high:98388kB active_anon:94857072kB inactive_anon:256kB active_file:3492kB inactive_file:3120kB unevictable:0kB isolated(anon):0kB isolated(file):128kB present:97517568kB managed:95925820kB mlocked:0kB dirty:0kB writeback:0kB mapped:996kB shmem:620kB slab_reclaimable:72616kB slab_unreclaimable:35820kB kernel_stack:4752kB pagetables:227860kB unstable:0kB bounce:0kB free_pcp:2560kB local_pcp:0kB free_cma:0kB writeback_tmp:0kB pages_scanned:9970 all_unreclaimable? yes
lowmem_reserve[]: 0 0 0 0

可以看到Normal還有85808KB窟感,DMA32還有376572 KB,DMA還有15908KB歉井,
各個(gè)zone的free都大于min,分配是有鏈條的柿祈,Normal不夠了,會(huì)從DMA32以及DMA去請(qǐng)求分配哩至,所以為什么分配失敗了呢躏嚎?

雖然說(shuō)分配內(nèi)存會(huì)按照Normal、DMA32菩貌、DMA的順序去分配卢佣,但是低端內(nèi)存相對(duì)來(lái)說(shuō)更寶貴些,為了防止低端內(nèi)存被高端內(nèi)存用完箭阶,珠漂,linux設(shè)計(jì)了保護(hù)機(jī)制晚缩,也就是lowmen_reserve,從上面的日志看媳危,他們的值是這樣的:

  • DMA(index=0): lowmem_reserve[]:0 2825 96503 96503
  • DMA32(index=1)owmem_reserve[]: 0 0 93677 93677
  • DMA32(index=2)lowmem_reserve[]: 0 0 0 0

lowmen_reserve的值是一個(gè)數(shù)組荞彼,當(dāng)Normal(index=2)像DMA32申請(qǐng)內(nèi)存的時(shí)候,需要滿足條件:
DMA32 high+lowmem_reserve[2] < free待笑,才能申請(qǐng)鸣皂,來(lái)算下:

  • Normal:從自己這里申請(qǐng),free(85808kB) > min(65592kB )暮蹂,可以申請(qǐng)寞缝,但是只能申請(qǐng) 85808kB-65592kB = 20216kb,不夠申請(qǐng)的內(nèi)存仰泻,所以申請(qǐng)失敗了(watermark[min]以下的內(nèi)存屬于系統(tǒng)的自留內(nèi)存荆陆,用以滿足特殊使用,所以不會(huì)給用戶態(tài)的普通申請(qǐng)來(lái)用)

  • Normal轉(zhuǎn)到DMA32申請(qǐng):high(2964kB) + lowmem_reserve2*4 > DMA32 Free(376572kB),不允許申請(qǐng)

  • Normal轉(zhuǎn)到DMA申請(qǐng):high(12kB) + lowmem_reserve2*4 > DMA Free(15908kB),不允許申請(qǐng),所以….最終失敗了

min_free_kbytes
這里屬于擴(kuò)展知識(shí)了集侯,和分析oom問(wèn)題不大被啼。我們知道了每個(gè)區(qū)都有min、low棠枉、high浓体,那他們是怎么計(jì)算出來(lái)的,就是根據(jù)min_free_kbytes計(jì)算出來(lái)的辈讶,他本身在系統(tǒng)初始化的時(shí)候計(jì)算命浴,最小128K,最大64M

  • watermark[min] = min_free_kbytes換算為page單位即可贱除,假設(shè)為min_free_pages生闲。(因?yàn)槭敲總€(gè)zone各有一套watermark參數(shù),實(shí)際計(jì)算效果是根據(jù)各個(gè)zone大小所占內(nèi)存總大小的比例月幌,而算出來(lái)的per zone min_free_pages)
  • watermark[low] = watermark[min] * 5 / 4
  • watermark[high] = watermark[min] * 3 / 2

min 和 low的區(qū)別

  • min下的內(nèi)存是保留給內(nèi)核使用的碍讯;當(dāng)?shù)竭_(dá)min,會(huì)觸發(fā)內(nèi)存的direct reclaim
  • low水位比min高一些飞醉,當(dāng)內(nèi)存可用量小于low的時(shí)候冲茸,會(huì)觸發(fā) kswapd回收內(nèi)存屯阀,當(dāng)kswapd慢慢的將內(nèi)存 回收到high水位缅帘,就開(kāi)始繼續(xù)睡眠

3)被干掉進(jìn)程信息

[21367253.169980] Out of memory: Kill process 13599 (redis-server) score 270 or sacrifice child
[21367253.171663] Killed process 13599 (redis-server) total-vm:32972052kB, anon-rss:26658828kB, file-rss:88kB, shmem-rss:0kB

被kill的進(jìn)程pid是13599.進(jìn)程所占用的內(nèi)存頁(yè)是 6664731,換算內(nèi)存大概占用 換算為內(nèi)存占用量是6664731*4096 = 26GB和 anon-rss:26658828kB顯示占用的內(nèi)存差不多难衰。

[21367253.103259] [ pid ]   uid  tgid total_vm      rss nr_ptes swapents oom_score_adj name
[21367253.105522] [ 3086]     0  3086    20024       87      45        0             0 systemd-journal
[21367253.107824] [ 5969]     0  5969     6718      217      18        0             0 systemd-logind
[21367253.110105] [ 5970]    81  5970    14564      179      31        0          -900 dbus-daemon
[21367253.112372] [ 5983]     0  5983   615231   

進(jìn)程輸出的含義是:

  • pid進(jìn)程ID钦无。
  • uid用戶ID。
  • tgid線程組ID盖袭。
  • total_vm虛擬內(nèi)存使用(單位為4 kB內(nèi)存頁(yè))
  • rss 常駐內(nèi)存使用(單位4 kB內(nèi)存頁(yè))
  • nr_ptes頁(yè)表項(xiàng)
  • swapents交換條目
  • oom_score_adj通常為0;較低的數(shù)字表示當(dāng)調(diào)用OOM殺手時(shí)失暂,進(jìn)程將不太可能死亡彼宠。 值越高越被系統(tǒng)有限結(jié)束進(jìn)程。

(4)解決辦法
這個(gè)redis進(jìn)程占用了近26G的內(nèi)存弟塞,而redis配置文件最大配置的內(nèi)存是20G凭峡,也就是除了20g數(shù)據(jù)占用的內(nèi)存,程序進(jìn)程本身占用了近6G的數(shù)據(jù)决记。我們服務(wù)器可用內(nèi)存是98G摧冀,之所以這次內(nèi)存會(huì)不夠用的原因是這臺(tái)服務(wù)器部署了5個(gè)redis節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)的最大可用內(nèi)存設(shè)置都是20G系宫,這次由于大量寫(xiě)入數(shù)據(jù)導(dǎo)致redis節(jié)點(diǎn)內(nèi)存暴增索昂。所以解決辦法就是減少部署的節(jié)點(diǎn),比如機(jī)器總共內(nèi)存是98G扩借,最多部署4個(gè)節(jié)點(diǎn)椒惨,還有就是增減內(nèi)存占用閾值報(bào)警監(jiān)控,另外就是大量數(shù)據(jù)寫(xiě)入前檢查機(jī)器節(jié)點(diǎn)內(nèi)存是否夠用潮罪。

擴(kuò)展

1.什么是oom killer

他是Linux內(nèi)核設(shè)計(jì)的一種機(jī)制康谆,在內(nèi)存不足的會(huì)后,選擇一個(gè)占用內(nèi)存較大的進(jìn)程并kill掉這個(gè)進(jìn)程错洁,以滿足內(nèi)存申請(qǐng)的需求(內(nèi)存不足的時(shí)候該怎么辦秉宿,其實(shí)是個(gè)兩難的事情,oom killer算是提供了一種方案吧)

2.在什么時(shí)候觸發(fā)屯碴?

在內(nèi)存不足的時(shí)候觸發(fā)描睦,再往細(xì)節(jié)看,主要牽涉到【linux的物理內(nèi)存結(jié)構(gòu)】和【overcommit機(jī)制】
2.1 內(nèi)存結(jié)構(gòu) node导而、zone忱叭、page、order
對(duì)于物理內(nèi)存內(nèi)存今艺,linux會(huì)把它分很多區(qū)(zone)韵丑,zone上還有node的概念,zone下面是很多page虚缎,這些page是根據(jù)buddy分配算法組織的

上面的概念做下簡(jiǎn)單的介紹撵彻,對(duì)后面分析oom killer日志很有必要:

Node:每個(gè)CPU下的本地內(nèi)存節(jié)點(diǎn)就是一個(gè)Node,如果是UMA架構(gòu)下实牡,就只有一個(gè)Node0,在NUMA架構(gòu)下陌僵,會(huì)有多個(gè)Node
Zone:每個(gè)Node會(huì)劃分很多域Zone,大概有下面這些

  1. ZONE_DMA:定義適合DMA的內(nèi)存域创坞,該區(qū)域的長(zhǎng)度依賴于處理器類型碗短。比如ARM所有地址都可以進(jìn)行DMA,所以該值可以很大题涨,偎谁,或者干脆不定義DMA類型的內(nèi)存域总滩。而在IA-32的處理器上,一般定義為16M巡雨。
  2. ZONE_DMA32:只在64位系統(tǒng)上有效闰渔,為一些32位外設(shè)DMA時(shí)分配內(nèi)存。如果物理內(nèi)存大于4G铐望,該值為4G澜建,否則與實(shí)際的物理內(nèi)存大小相同。
  3. ZONE_NORMAL:定義可直接映射到內(nèi)核空間的普通內(nèi)存域蝌以。在64位系統(tǒng)上炕舵,如果物理內(nèi)存小于4G,該內(nèi)存域?yàn)榭崭6?2位系統(tǒng)上咽筋,該值最大為896M。
  4. ZONE_HIGHMEM:只在32位系統(tǒng)上有效徊件,標(biāo)記超過(guò)896M范圍的內(nèi)存奸攻。在64位系統(tǒng)上,由于地址空間巨大虱痕,超過(guò)4G的內(nèi)存都分布在ZONE_NORMA內(nèi)存域睹耐。
  5. ZONE_MOVABLE:偽內(nèi)存域,為了實(shí)現(xiàn)減小內(nèi)存碎片的機(jī)制部翘。

分配價(jià)值鏈

  • 除了只能在某個(gè)區(qū)域分配的內(nèi)存(比如ZONE_DMA)硝训,普通的內(nèi)存分配會(huì)有一個(gè)“價(jià)值”的層次結(jié)構(gòu),按分配的“廉價(jià)度”依次為:ZONE_HIGHMEM > ZONE_NORMAL > ZONE_DMA新思。
  • 即內(nèi)核在進(jìn)行內(nèi)存分配時(shí)窖梁,優(yōu)先從高端內(nèi)存進(jìn)行分配,其次是普通內(nèi)存夹囚,最后才是DMA內(nèi)存

Page zone下面就是真正的內(nèi)存頁(yè)了纵刘,每個(gè)頁(yè)基礎(chǔ)大小是4K,他們維護(hù)在一個(gè)叫free_area的數(shù)組結(jié)構(gòu)中荸哟。

  • order:數(shù)組的index假哎,也叫order,實(shí)際對(duì)應(yīng)的是page的大小鞍历,比如order為0舵抹,那么就是一堆1個(gè)空閑頁(yè)(4K)組成的鏈表,order為1堰燎,就是一堆2個(gè)空閑頁(yè)(8K)組成的鏈表掏父,order為2笋轨,就是一堆4個(gè)空閑頁(yè)(16K)組成的鏈表

2.2 overcommit
根據(jù)2.1秆剪,已經(jīng)知道物理內(nèi)存的大概結(jié)構(gòu)以及分配的規(guī)則赊淑,不過(guò)實(shí)際上還有虛擬內(nèi)存的存在,他的overcommit機(jī)制和oom killer有很大關(guān)系:

在實(shí)際申請(qǐng)內(nèi)存的時(shí)候仅讽,比如申請(qǐng)1G陶缺,并不會(huì)在物理區(qū)域中分配1G的真實(shí)物理內(nèi)存,而是分配1G的虛擬內(nèi)存洁灵,等到需要的時(shí)候才去真正申請(qǐng)物理內(nèi)存饱岸,也就是說(shuō)申請(qǐng)不等于分配

所以說(shuō),可以申請(qǐng)比物理內(nèi)存實(shí)際大的內(nèi)存徽千,也就是overcommit苫费,這樣會(huì)面臨一個(gè)問(wèn)題,就是當(dāng)真的需要這么多內(nèi)存的時(shí)候怎么辦—>oom killer!

vm.overcommit_memory 接受三種值:

  • 0 – Heuristic overcommit handling. 這是缺省值双抽,它允許overcommit百框,但過(guò)于明目張膽的overcommit會(huì)被拒絕,比如malloc一次性申請(qǐng)的內(nèi)存大小就超過(guò)了系統(tǒng)總內(nèi)存
  • 1 – Always overcommit. 允許overcommit牍汹,對(duì)內(nèi)存申請(qǐng)來(lái)者不拒铐维。
  • 2 – Don’t overcommit. 禁止overcommit。

3.oom killer 怎么挑選進(jìn)程慎菲?

linux會(huì)為每個(gè)進(jìn)程算一個(gè)分?jǐn)?shù)嫁蛇,最終他會(huì)將分?jǐn)?shù)最高的進(jìn)程kill

/proc/<pid>/oom_score_adj

  • 在計(jì)算最終的 badness score 時(shí),會(huì)在計(jì)算結(jié)果是中加上 oom_score_adj露该,取值范圍為-1000到1000
  • 如果將該值設(shè)置為-1000睬棚,則進(jìn)程永遠(yuǎn)不會(huì)被殺死,因?yàn)榇藭r(shí) badness score 永遠(yuǎn)返回0解幼。

/proc/<pid>/oom_adj

  • 取值是-17到+15闸拿,取值越高,越容易被干掉书幕。如果是-17新荤,則表示不能被kill
  • 該設(shè)置參數(shù)的存在是為了和舊版本的內(nèi)核兼容

/proc/<pid>/oom_score

  • 這個(gè)值是系統(tǒng)綜合進(jìn)程的內(nèi)存消耗量、CPU時(shí)間(utime + stime)台汇、存活時(shí)間(uptime - start time)和oom_adj計(jì)算出的苛骨,消耗內(nèi)存越多分越高,存活時(shí)間越長(zhǎng)分越低

子進(jìn)程內(nèi)存:
Linux在計(jì)算進(jìn)程的內(nèi)存消耗的時(shí)候苟呐,會(huì)將子進(jìn)程所耗內(nèi)存的一半同時(shí)算到父進(jìn)程中痒芝。這樣,那些子進(jìn)程比較多的進(jìn)程就要小心了牵素。
關(guān)閉 OOM killer

  • sysctl -w vm.overcommit_memory=2
  • echo “vm.overcommit_memory=2” >> /etc/sysctl.conf

3.1 找出最優(yōu)可能被殺掉的進(jìn)程

vi oomscore.sh

#!/bin/bash
for proc in $(find /proc -maxdepth 1 -regex '/proc/[0-9]+'); do
    printf "%2d %5d %s\n" \
        "$(cat $proc/oom_score)" \
        "$(basename $proc)" \
        "$(cat $proc/cmdline | tr '\0' ' ' | head -c 50)"
done 2>/dev/null | sort -nr | head -n 10

chmod +x oomscore.sh
./oomscore.sh

3.2 避免的oom killer的方案

  • 直接修改/proc/PID/oom_adj文件严衬,將其置位-17
  • 修改/proc/sys/vm/lowmem_reserve_ratio
  • 直接關(guān)閉oom-killer

參考:

http://bhsc881114.github.io/2018/06/24/oom-killer%E7%90%86%E8%A7%A3%E5%92%8C%E6%97%A5%E5%BF%97%E5%88%86%E6%9E%90-%E6%97%A5%E5%BF%97%E5%88%86%E6%9E%90/

http://bhsc881114.github.io/2018/06/24/oom%20killer%E7%90%86%E8%A7%A3%E5%92%8C%E6%97%A5%E5%BF%97%E5%88%86%E6%9E%90:%E7%9F%A5%E8%AF%86%E5%82%A8%E5%A4%87/

https://blog.51cto.com/leejia/1952482

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市笆呆,隨后出現(xiàn)的幾起案子请琳,更是在濱河造成了極大的恐慌粱挡,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俄精,死亡現(xiàn)場(chǎng)離奇詭異询筏,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)竖慧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)嫌套,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人圾旨,你說(shuō)我怎么就攤上這事踱讨。” “怎么了砍的?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵勇蝙,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我挨约,道長(zhǎng)味混,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任诫惭,我火速辦了婚禮翁锡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘夕土。我一直安慰自己馆衔,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布怨绣。 她就那樣靜靜地躺著角溃,像睡著了一般。 火紅的嫁衣襯著肌膚如雪篮撑。 梳的紋絲不亂的頭發(fā)上减细,一...
    開(kāi)封第一講書(shū)人閱讀 51,125評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音赢笨,去河邊找鬼未蝌。 笑死,一個(gè)胖子當(dāng)著我的面吹牛茧妒,可吹牛的內(nèi)容都是我干的萧吠。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼桐筏,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼纸型!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狰腌,失蹤者是張志新(化名)和其女友劉穎除破,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體癌别,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年蹋笼,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了展姐。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡剖毯,死狀恐怖圾笨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情逊谋,我是刑警寧澤擂达,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站胶滋,受9級(jí)特大地震影響板鬓,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜究恤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一俭令、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧部宿,春花似錦抄腔、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至雾叭,卻和暖如春悟耘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背织狐。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來(lái)泰國(guó)打工作煌, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赚瘦。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓粟誓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親起意。 傳聞我的和親對(duì)象是個(gè)殘疾皇子鹰服,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容