繁体   English   中英

内存泄漏使用malloc失败

[英]Memory Leak Using malloc fails

我正在编写一个泄漏内存(主内存)的程序来测试系统在低系统内存和交换内存时的行为方式。 我们使用以下循环定期运行并泄漏内存

main(int argc, char* argv[] )  
{
   int arg_mem = argv[1];

        while(1)
        {
          u_int_ptr =(unsigned int*)  malloc(arg_mem * 1024 * 1024);

        if( u_int_ptr == NULL )
           printf("\n leakyapp Daemon FAILED due to insufficient available memory....");

          sleep( arg_time );
        }

}

上面的循环运行一段时间并打印消息“leakyapp Daemon FAILED由于可用内存不足......”。 但是当我运行命令“free”时,我可以看到运行该程序对主内存或交换没有影响。

难道我做错了什么 ?

在您实际写入之前,物理内存不会提交给您的分配。

如果在2.6.23之后有内核版本,请使用带有MAP_POPULATE标志的mmap()而不是malloc()

u_int_ptr = mmap(NULL, arg_mem * 1024 * 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_POPULATE, -1, 0);

if (u_int_ptr == MAP_FAILED)
    /* ... */

如果您有较旧的内核,则必须触摸分配中的每个页面。

可能存在某种写时复制优化。 我建议实际上写一些东西给你正在分配的内存。

发生的事情是malloc从堆请求argmem * 256页(假设页面大小为4 KB)。 堆反过来从操作系统请求内存。 但是,所有这一切都是在页表中为新分配的内存块创建条目。 除了堆跟踪malloc请求所需的物理RAM之外,没有为该进程分配实际的物理RAM。

一旦进程尝试通过读取写入访问其中一个页面,就会生成页面错误,因为页面表中的条目实际上是一个悬空指针。 然后,操作系统将为该进程分配一个物理页面。 只有这样你才能看到可用的物理内存下降。

由于所有新页面都开始完全清零,因此Linux可能会采用“写入时复制”策略来优化页面分配。 即,它可能会使单个页面完全归零,并且当进程尝试从先前未使用的页面读取时始终分配该页面。 只有当进程尝试写入该新页面时,它才会实际从物理RAM分配一个完全新鲜的页面。 我不知道Linux是否真的这样做,但如果确实如此,仅仅从新页面读取不足以增加物理内存使用量。

所以,你最好的策略是分配你的大块RAM,然后以4096字节的间隔写一些东西。

ulimit -m -v打印什么?

说明:在任何服务器操作系统上,您可以限制进程可以分配的资源量,以确保单个失控进程无法关闭整个计算机。

我猜测(基于命令行参数)您使用的是桌面/服务器操作系统,而不是嵌入式系统。

像这样分配内存可能不会消耗太多RAM。 您的内存分配可能甚至没有成功 - 在某些操作系统(例如Linux)上,即使您要求的内存多于可用内存, malloc()也可以返回非NULL。

在不知道您的操作系统是什么以及您正在尝试测试的内容的情况下,很难建议任何特定的内容,但您可能希望查看比malloc()更多低级别的内存分配方式,或者控制虚拟内存系统的方法。 在Linux上你可能想看看mlock()

我认为caf已经解释过了。 Linux通常配置为允许过度使用内存。 你分配了大量的内存,但内部却没有发生任何事情,只是记下你处理过的大量内存。 在您尝试编写该块之前,内核不会尝试查找可用的虚拟内存来满足读/写访问。 这有点像航班预订:航空公司通常会超额预订航班,因为总有一部分乘客没有出现。

您可以通过在分配后使用memset()写入块来强制提交内存。 calloc应该工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM