MySQLOOM系列Linux内存分配
我们想说今天是一个在线的4G的RDS实例,具有OOM问题(内存),和MySQL进程已经下降直接被杀死。在解释这个问题,我们首先需要从Linux系统的内存分配政策开始。
一般来说,写C语言程序。我们习惯于使用malloc申请内存空间动态(java的JVM负责内存管理)。malloc函数将连续的存储单元的操作系统,然后再回到这个空间的起始地址。如果malloc函数返回null,它表示没有分配的内存空间的系统。这是我们一般人的想法,当然,这是真正的一些操作系统(Solaris)。
但Linux是没有的情况下,Linux内存分配是采取更积极的配置策略,假定内存空间的应用和不立即使用它,所以允许一定量的超售,当应用程序需要使用它时,操作系统可能已被其他应用程序内存空间,成为能满足应用,需要简单的说,就是允许应用于实际空间的分配(包括物理内存和交换)更大的内存,这一特性称为过量使用。
这个功能在Linux操作系统中也可用,而过量使用政策可以调整,通过设置 /过程/系统/ overcommit_memory不同价值观。
overcommit_memory可以采取3值:
0:默认值,确定是否超售和超售的Linux内核的大小通过一些启发式算法,一般允许轻微的超售,拒绝要求显然不可能,做一些规则和限制,如不同用户过量使用不一样的大小。
1:允许,当然不超售,限制,这并不是无限的,它也是由寻址空间的限制。32位的系统可能是4G,而64位系统约16吨。
2:禁止和禁止超售。由系统分配的内存不会超过*互换+物理内存overcommit_ratio。价值可以通过/proc / / / overcommit_ratio VM系统,,默认是50%。
为了验证Linux的内存分配,我们使用了一个小程序来测试它。
#包括
#包括
#定义兆1024×1024
int main(int argc、argv char * { })
{
void *泮佛罗宁= null;
int计数= 0;
(1)
{
泮佛罗宁=(void *)malloc(兆字节);
如果(!Myblock)打破;
printf(目前分配%d MB
}
出口(0);
}
#包括
#包括
#定义兆1024×1024
int main(int argc、argv char * { })
{
void *泮佛罗宁= null;
int计数= 0;
(1)
{
泮佛罗宁=(void *)malloc(兆字节);
如果(!Myblock)打破;
memset(泮佛罗宁,1 MB);
printf(目前分配%d MB
}
出口(0);
}
前者适用于存储空间通过malloc()和不立即使用它。相反,后者在每次应用程序之后都充满了1,让我们看看两个程序运行的结果。
这是在1G的RAM、400米交换虚拟机上运行的结果。前者比实际内存占用更多的空间,后者不超过实际可用内存空间,这验证了前面描述的Linux的内存分配策略。
这是一个系统的优化。但我们知道,超售是基于这样的假设,不会有大量的项目在同一时间使用资源,这显然也是有风险的。所以,Linux也使用机制OOM Killer(出内存杀手),在系统的可用内存(包括交换)即将被使用,选择性地杀死一些进程释放一些内存。在下一章中,我们专注于Linux的OOM杀手的机制。