加入收藏 | 设为首页 | 会员中心 | 我要投稿 云计算网_泰州站长网 (http://www.0523zz.com/)- 视觉智能、AI应用、CDN、行业物联网、智能数字人!
当前位置: 首页 > 站长学院 > PHP教程 > 正文

Linux 下malloc的分析

发布时间:2021-11-20 14:45:33 所属栏目:PHP教程 来源:互联网
导读:程序如下 #includestdio.h #includestdlib.h int mian() { int *p; int i=0; while(1) { p=(int *)malloc(sizeof(char)*1024*1024); i++; printf(%dMn,i); } } 运行的结果让我和我的小伙伴都惊呆了 。。。居然能分配100G+。。并且还能继续分配。。当时就吓

程序如下
 
#include<stdio.h>
#include<stdlib.h>
 
int mian()
{
    int *p;
    int i=0;
    while(1)
    {
        p=(int *)malloc(sizeof(char)*1024*1024);
        i++;
        printf("%dMn",i);
    }
 
}
 
 
运行的结果让我和我的小伙伴都惊呆了 。。。居然能分配100G+。。并且还能继续分配。。当时就吓尿了啊。。。
 
哥这破二手电脑也就只有40G的内存啊。。怎么能分配这么多呢?
 
于是哥又想到了内存泄漏,可能每次内存如果没有指针去指向它的话可能就直接释放了。
 
于是
 
 p=(int *)malloc(sizeof(char)*1024*1024*(i+1));
 
居然还是和原来一样!!!看来原来C学C的时候还是学的太浅了啊。。
 
然后又想到是不是没有使用那一块内存,所以gcc直接优化掉了。
 
于是就在分配内存下面增加了一条语句
 
memset(p,i,sizeof(char)*1024*1024)
 
分配语句改成第一次的样子。
 
这次总算是正常了。前800M都是很快出来。估计是可以直接用内存的原因(只有1G内存)。
 
但是后面的就出来很慢了。大概一秒也就刷5到6行的样子。个人猜测可能是用到了虚拟内存的缘故,不断的IO操作,让速度慢了很多。
 
到1200M在左右的时就基本就不能动了。。所以只好乖乖的等待被内核干掉了。
 
大概8分钟左右的样子,程序出现了Out of memory的字样。提示说结束进程或者牺牲掉孩子(英语不好。。)。
 
然后下面两排提示杀掉了进程,行尾显示:total -vm 2728124KB  anon -rss 869736KB  file -rss 88KB
 
最后排就显示个killed.
 
于是问题又来了。这些数字是个什么意思呢。。
 
total 意思估计就是总的大小吧。已经分配了的磁盘+内存空间大小。
 
anon的意思就没这么容易看出来了。不过从之前的观察来看,似乎是内存使用的大小。
 
file 这个如果是文件的长度,似乎不太对头啊。估计是内核分配给程序的初始空间大小吧。
 
查了下swap的大小,2015.99M=2064373.76k。用total-anon差不多180000+K的样子,还没有把磁盘交换区占满,估计是还有其他程序也占用了吧。
 
弄了半天,malloc分配的空间,好像除了物理限制,似乎没有给设定一个最大分配的值啊。果断用man来查查看。
 
man这个东西还是好啊,又学了很多东西。
 
第一段:
 
 malloc这个函数通常是在程序内存堆中用sbrk这个函数来分配空间。并且是有限制的,在MMAP_THRESHOLD中设置了上限,默认大小是128K,可以用mallopt()来调整。
 
超过128K之后则用mmap来分配内存空间,并且不受RLIMIT_DATA(通过getrlimit设置)的影响。那RLIMIT_DATA是个什么呢?下面是百度上的解释。
 
一个进程的数据段最大字节长度。数据段中初始化数据、非初始化数据以及堆的总和。当调用函数brk动态改变一个进程的数据段大小时,若失败,errno值将被设置为ENOMEM。
 
真是越看越觉得自己了解的少啊。。为什么要设置这个RLIMIT_DATA呢。。为何mmap可以不受RLIMIT_DATA影响呢。。以后再慢慢学吧。
 
第二段:
 
一般glibc库中是默认会自动设置错误信息的。如果自己写一个当然就不一定了(废话。。)。另外,还有一个MALLOC_CHECK_可以用来设置检查错误的强度。
 
貌似设置成0就可以无限分配内存了?估计电脑会直接挂掉吧。。。
 
第三段(malloc有BUG!):
 
如果没有内存分配的时候,malloc会返回一个non-NULL(估计是个NULL),并不保证这块内存可以使用。然后系统会了解到内存没有了,还会通过OOM来乱杀进程。
 
但是刚才看OOM的资料时说,OOM会给每个进程打分,分最高的会被杀掉。这么看来。。这个BUG是不是就没有了。。
 
不过在多进程的情况下,可能在刚换到另一进程的时候,这个进程又分配了一点空间和之前那个准备杀掉的进程一样。这样就可能杀掉其他无关进程了。
 
当然这样的情况还与kill设置有关,最后还是得看OOM怎么实现的。
 
最后,sbrk和brk还有mmap也是内存分配的函数,只是没有malloc用的那么方便。mmap直接映射到内存,效率估计比操作数据段的brk和sbrk要快得多吧。

(编辑:云计算网_泰州站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读