zoukankan      html  css  js  c++  java
  • [Android Memory] Linux下malloc函数和OOM Killer

    http://www.linuxidc.com/Linux/2010-09/28364.htm
    Linux下malloc函数主要用来在用户空间从heap申请内存,申请成功返回指向所分配内存的指针,申请失败返回NULL。默认情况下,Linux内核使用“乐观的”分配内存策略,首先粗略估计系统可使用的内存数,然后分配内存,但是在使用的时候才真正把这块分配的内存给你。这样一来,即使用malloc申请内存没有返回NULL,你也不一定能完全使用这块内存,特别是在一次或连续多次申请很多内存的时候。
     
    如果一直连续用malloc申请内存,而不真正使用,所申请的内存总数可以超过真正可以使用的内存数。但是当真正使用这块内存,比如用memset或bzero函数一次性把所申请到的大块内存“使用掉”,Linux系统就会Out Of Memory,这个时候OOM Killer就会kill掉用户空间的其他进程来腾出更多可使用内存。
     
    OOM Killer根据OOM score来决定kill哪个进程,OOM score可以看/proc/<PID>/oom_score,score由badness函数计算得出,根据进程运行时间长短,进程优先级,进程所使用的内存数等等。可以通过/proc/<PID>/oom_adj来干预计算socre,这个值的取值范围是-17~15,如果是-17该进程就永远不会被kill(这个可能也和内核版本有关,不见得所有内核版本都支持,得实际试试)。
     
    “默认情况”Linux是这种做的,“默认情况”是指/proc/sys/vm/overcommit_memory为0的时候。这个参数也可以调整,如果为1表示“来着不拒”,只要你malloc过来申请,我啥都不做,立马给你分配内存,这样的话性能就会有大幅度的提高;如果为2表示Linux会精确计算所有可使用的内存和所申请的内存,如果所申请的超过的可使用的内存数就返回NULL。可使用的内存值计算方法,虚拟内存(swap)+ /proc/sys/vm/overcommit_memory(百分比) × 物理内存。/proc/sys/vm/overcommit_memory默认值为50,计算起来就是50%的物理内存数。
     
    Linux自身内核会占一部分内存,还有buffer/cache所占用的内存,所以实际上能被malloc申请后使用的内存并非物理内存大小,demsg的输出里面包含了相关信息(如果看不到,可能是被别的信息冲掉了,重启系统,在系统起来后马上看):
    Memory: 2071220k/2097152k available (2122k kernel code, 24584k reserved, 884k data, 228k init, 1179584k highmem)
     
    关于OOM Killer的proc文件系统
     
    http://book.2cto.com/201302/16321.html
     

    下面开始介绍与OOM Killer相关的proc文件系统。
    /proc/<PID>/oom_adj

    为/proc/<PID>/oom_adj设置值就可以调整得分。调整值的范围为–16~15。正的值容易被OOM Killer选定。负值可能性较低。例如,当指定3时,得分就变为23倍;当指定–5时,得分就变为1/25。

    “–17”是一个特殊的值。如果设置为–17,就会禁止OOM Killer发出的信号(从Linux 2.6.12开始支持设置–17)。

    在OOM Killer运行的情况下,为了实现远程登录而想要将sshd排除在对象外时,可以执行下列命令。
    # cat /proc/'cat /var/run/sshd.pid'/oom_score
    15
    # echo -17 >  /proc/'cat /var/run/sshd.pid'/oom_adj
    # tail /proc/'cat /var/run/sshd.pid'/oom_*
    ==> /proc/2278/oom_adj <==
    -17
    ==> /proc/2278/oom_score <==
    0                               /*得分变成0*/

    Linux 2.6.18开始可以使用/proc/<PID>/oom_adj。内容记载在Documentation /filesystems/proc.txt中。
    /proc/sys/vm/panic_on_oom

    将/proc/sys/vm/panic_on_oom设置为1时,在OOM Killer运行时可以不发送进程信号,而是使内核产生重大故障。
    # echo 1 > /proc/sys/vm/panic_on_oom
    /proc/sys/vm/oom_kill_allocating_task

    从Linux 2.6.24开始proc文件系统就有oom_kill_allocating_task。如果对此设置除0以外的值,则促使OOM Killer运行的进程自身将接收信号。此处省略对所有进程的得分计算过程。
    # echo 1 > /proc/sys/vm/oom_kill_allocating_task

    这样就不需要参照所有进程,但是也不会考虑进程的优先级和root权限等,只发送信号。
    /proc/sys/vm/oom_dump_tasks

    从Linux 2.6.25开始,将oom_dump_tasks设置为除0以外的值时,在OOM Killer运行时的输出中会增加进程的列表信息。

    下面为设置示例。
    # echo 1 > /proc/sys/vm/oom_dump_tasks

    列表信息显示如下,可以使用dmesg或syslog来确认。
    [ pid ]   uid  tgid total_vm      rss cpu oom_adj name
    [    1]     0     1     2580        1   0       0 init
    [  500]     0   500     3231        0   1     -17 udevd
    [ 2736]     0  2736     1470        1   0       0 syslogd
    [ 2741]     0  2741      944        0   0       0 klogd
    [ 2765]    81  2765     5307        0   0       0 dbus-daemon
    [ 2861]     0  2861      944        0   0       0 acpid
    ...
    [ 3320]     0  3320   525842   241215   1       0 stress
    /proc/<PID>/oom_score_adj

    从Linux 2.6.36开始都安装了/proc/<PID>/oom_score_adj,此后将替换为/proc/ <PID>/oom_adj。详细内容请参考Documentation/feature-removal-schedules.txt。即使当前是对/proc/<PID>/oom_adj进行的设置,在内核内部进行变换后的值也是针对/proc/<PID>/oom_score_adj设置的。

    /proc/<PID>/oom_score_adj可以设置–1000~1000之间的值。设置为–1000时,该进程就被排除在OOM Killer强制终止的对象外。

    在内核2.6.36以后的版本中写入oom_adj,只会输出一次如下的信息。
    # dmesg
    .....
    udevd (60): /proc/60/oom_adj is deprecated, please use /proc/60/oom_score_adj instead.

  • 相关阅读:
    ASP.NET Forms验证(自定义、角色提供程序)B
    SPSiteDataQuery使用说明
    moss2010 仿内容查询部件代码
    微软CRM系统二次开发步骤以及注意事项
    sap ABAP关于Data Reference的使用FIELDSYMBOLS
    selectoptions 模拟parmater
    ABAP "FOR ALL ENTRIES IN" 使用指南
    ABAP/4中参数的传递
    用接口CL_GUI_FRONTEND_SERVICES弹出选择文件对话框
    深入浅出理解索引结构
  • 原文地址:https://www.cnblogs.com/0616--ataozhijia/p/4038295.html
Copyright © 2011-2022 走看看