linux下内存分配的管理主要通过内核参数来控制:
1.与容量相关的内存可调参数
以下参数位于 proc 文件系统的 /proc/sys/vm/ 目录中。
overcommit_memory :规定决定是否接受超大内存请求的条件。这个参数有三个可能的值:
* 0 — 默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。不让过度使用,直接报错
* 1 — 内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。应用程序在需要时分配,允许过度使用
* 2 — 内存拒绝等于或者大于总可用 swap 大小以及 overcommit_ratio 指定的物理 RAM 比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。 将swap直接使用,使用的内存 = swap + ram * 50%
注意:只为 swap 区域大于其物理内存的系统推荐这个设置
overcommit_ratio
将 overcommit_memory 设定为 2 时,指定所考虑的物理 RAM 比例。默认为 50。
测试程序:
###############################################################################
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#define maxtimes 1000*1000
#define unit 10485760
int main()
{
char *q[1000000];
int i=1;
char *pc;
for (i=1; i<=maxtimes;i++)
{
q[i] = (char *)malloc(unit);
if ( q[i] == NULL)
{
printf ("malloc error\n");
}
printf("%o\n",q[i]);
pc = (char*)(q[i]);
for (int j=0;j<10485760;j++)
{
pc[j]='a';
}
printf("%s\n",pc);
printf("have been malloc %dM\n",i);
}
return 0;
}
###############################################################################
测试1:overcommit_memory = 0 也是默认的情况,我物理内存2G,开机后查看已使用600M左右,我在这里关闭了swap分区,编译来测试,结果:使用top 查看a.out的RES(物理内存的使用)到达了1.3g 进程被Killed (原因在后面说) 1.3g+600多M = 2G 查看日志:
Jul 16 14:24:48 localhost kernel: Out of memory: kill process 19066 (a.out) score 131753 or a child
Jul 16 14:24:48 localhost kernel: Killed process 19066 (a.out) vsz:8432216kB, anon-rss:1377108kB, file-rss:92kB
测试2:overcommit_memory = 1,情况和测试1一致,
[root@localhost Desktop]# free
total used free shared buffers cached
Mem: 1978696 1873644 105052 0 8268 75012
-/+ buffers/cache: 1790364 188332
我们可以看到:内存在剩100M左右时,a.out先卡住了一会,然后有开始执行了 ,它会一直等待能够使用的资源再执行 (都是别的进程释放的资源),用来不会被杀死,因为这个模式对内存无限制
测试3:overcommit_memory = 2,overcommit_ratio默认,都使用,内存会在一定剩余的情况下不能malloc
程序执行结果:
have been malloc 266M 这里是2660
malloc error
0
Segmentation fault (core dumped)
o: VIRT -- Virtual Image (kb)
The total amount of virtual memory used by the task. It includes
all code, data and shared libraries plus pages that have been
swapped out. (Note: you can define the STATSIZE=1 environment vari-
able and the VIRT will be calculated from the /proc/#/state VmSize
field.)
VIRT = SWAP + RES.
p: SWAP -- Swapped size (kb)
The swapped out portion of a task’s total virtual memory image.
q: RES -- Resident size (kb)
The non-swapped physical memory a task has used.
2.Out-of-Memory Kill 可调参数
内存不足(OOM)指的是所有可用内存,包括 swap 空间都已被分配的计算状态。默认情况下,这个状态可造成系统 panic,并停止如预期般工作。但将 /proc/sys/vm/panic_on_oom 参数设定为 0 会让内核在出现 OOM 时调用 oom_killer 功能。通常 oom_killer 可杀死偷盗进程,并让系统正常工作。
可在每个进程中设定以下参数,提高您对被 oom_killer 功能杀死的进程的控制。它位于 proc 文件系统中 /proc/pid/ 目录下,其中 pid 是进程 ID。
oom_adj
定义 -16 到 15 之间的一个数值以便帮助决定某个进程的 oom_score。oom_score 值越高,被 oom_killer 杀死的进程数就越多。将 oom_adj 值设定为 -17 则为该进程禁用 oom_killer。
注意:
由任意调整的进程衍生的任意进程将继承该进程的 oom_score。例如:如果 sshd 进程不受 oom_killer 功能影响,所有由 SSH 会话产生的进程都将不受其影响。这可在出现 OOM 时影响 oom_killer 功能救援系统的能力。
1.与容量相关的内存可调参数
以下参数位于 proc 文件系统的 /proc/sys/vm/ 目录中。
overcommit_memory :规定决定是否接受超大内存请求的条件。这个参数有三个可能的值:
* 0 — 默认设置。内核执行启发式内存过量使用处理,方法是估算可用内存量,并拒绝明显无效的请求。遗憾的是因为内存是使用启发式而非准确算法计算进行部署,这个设置有时可能会造成系统中的可用内存超载。不让过度使用,直接报错
* 1 — 内核执行无内存过量使用处理。使用这个设置会增大内存超载的可能性,但也可以增强大量使用内存任务的性能。应用程序在需要时分配,允许过度使用
* 2 — 内存拒绝等于或者大于总可用 swap 大小以及 overcommit_ratio 指定的物理 RAM 比例的内存请求。如果您希望减小内存过度使用的风险,这个设置就是最好的。 将swap直接使用,使用的内存 = swap + ram * 50%
注意:只为 swap 区域大于其物理内存的系统推荐这个设置
overcommit_ratio
将 overcommit_memory 设定为 2 时,指定所考虑的物理 RAM 比例。默认为 50。
测试程序:
###############################################################################
#include "stdio.h"
#include "stdlib.h"
#include "errno.h"
#define maxtimes 1000*1000
#define unit 10485760
int main()
{
char *q[1000000];
int i=1;
char *pc;
for (i=1; i<=maxtimes;i++)
{
q[i] = (char *)malloc(unit);
if ( q[i] == NULL)
{
printf ("malloc error\n");
}
printf("%o\n",q[i]);
pc = (char*)(q[i]);
for (int j=0;j<10485760;j++)
{
pc[j]='a';
}
printf("%s\n",pc);
printf("have been malloc %dM\n",i);
}
return 0;
}
###############################################################################
测试1:overcommit_memory = 0 也是默认的情况,我物理内存2G,开机后查看已使用600M左右,我在这里关闭了swap分区,编译来测试,结果:使用top 查看a.out的RES(物理内存的使用)到达了1.3g 进程被Killed (原因在后面说) 1.3g+600多M = 2G 查看日志:
Jul 16 14:24:48 localhost kernel: Out of memory: kill process 19066 (a.out) score 131753 or a child
Jul 16 14:24:48 localhost kernel: Killed process 19066 (a.out) vsz:8432216kB, anon-rss:1377108kB, file-rss:92kB
测试2:overcommit_memory = 1,情况和测试1一致,
[root@localhost Desktop]# free
total used free shared buffers cached
Mem: 1978696 1873644 105052 0 8268 75012
-/+ buffers/cache: 1790364 188332
我们可以看到:内存在剩100M左右时,a.out先卡住了一会,然后有开始执行了 ,它会一直等待能够使用的资源再执行 (都是别的进程释放的资源),用来不会被杀死,因为这个模式对内存无限制
测试3:overcommit_memory = 2,overcommit_ratio默认,都使用,内存会在一定剩余的情况下不能malloc
程序执行结果:
have been malloc 266M 这里是2660
malloc error
0
Segmentation fault (core dumped)
o: VIRT -- Virtual Image (kb)
The total amount of virtual memory used by the task. It includes
all code, data and shared libraries plus pages that have been
swapped out. (Note: you can define the STATSIZE=1 environment vari-
able and the VIRT will be calculated from the /proc/#/state VmSize
field.)
VIRT = SWAP + RES.
p: SWAP -- Swapped size (kb)
The swapped out portion of a task’s total virtual memory image.
q: RES -- Resident size (kb)
The non-swapped physical memory a task has used.
2.Out-of-Memory Kill 可调参数
内存不足(OOM)指的是所有可用内存,包括 swap 空间都已被分配的计算状态。默认情况下,这个状态可造成系统 panic,并停止如预期般工作。但将 /proc/sys/vm/panic_on_oom 参数设定为 0 会让内核在出现 OOM 时调用 oom_killer 功能。通常 oom_killer 可杀死偷盗进程,并让系统正常工作。
可在每个进程中设定以下参数,提高您对被 oom_killer 功能杀死的进程的控制。它位于 proc 文件系统中 /proc/pid/ 目录下,其中 pid 是进程 ID。
oom_adj
定义 -16 到 15 之间的一个数值以便帮助决定某个进程的 oom_score。oom_score 值越高,被 oom_killer 杀死的进程数就越多。将 oom_adj 值设定为 -17 则为该进程禁用 oom_killer。
注意:
由任意调整的进程衍生的任意进程将继承该进程的 oom_score。例如:如果 sshd 进程不受 oom_killer 功能影响,所有由 SSH 会话产生的进程都将不受其影响。这可在出现 OOM 时影响 oom_killer 功能救援系统的能力。
来源:oschina
链接:https://my.oschina.net/u/817537/blog/145261