[英]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.