什么是脏私有内存?
Posted
技术标签:
【中文标题】什么是脏私有内存?【英文标题】:What is dirty private memory? 【发布时间】:2013-05-21 16:20:34 【问题描述】:我正在 64 位 Linux 系统上开发应用程序。正如我所看到的,我的应用程序正在消耗太多脏堆内存。说到堆内存,“脏”是什么意思?是什么导致了它的出现以及可以做些什么来防止它出现?
编辑
我最好解释一下我的应用程序执行什么操作。
我的应用程序在两个线程中运行:第一个线程将作业发送到队列,然后在另一个线程中执行。因此,第一个线程分配要排队的页面,第二个线程将它们出列,执行它们的作业并释放它们。所有这些操作都以线程安全的方式执行。
所以我对这个东西进行了测试,让它排队 100000000 个作业并执行它们。直到某个特定时刻,内存使用量才会增长。然后,当排队过程完成并且只剩下出队的时候,内存使用量莫名其妙地没有减少。最后,当所有作业都出列并执行时,所有内存都会被释放。因此,内存泄漏似乎发生在出队过程中,因为当它完成时所有内存都被释放,但我发现它的代码没有任何问题。
我知道如果我在这里发布我的代码会更好,但它太大了。但是,根据我添加的内容,是否有人猜测可能是什么原因造成的?
【问题讨论】:
你怎么看你有“脏堆内存”,你是怎么看的? @maazza 我看了一下/proc/PID/smaps
内存泄漏?检查valgrind
。
你应该用你的代码发布另一个问题,并留下一个链接作为介绍
【参考方案1】:
谈到即使释放一些块后内存不减少,您最好在匿名模式下使用mmap
,如下所示:
mmap(NULL, chunck_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
它不映射文件描述符并返回指向内存块的指针,当您取消映射时,该指针会立即返回给操作系统。但是,mmap
需要系统调用,这比 malloc 慢。因此,您应该使用mmap
来分配大页面。
【讨论】:
IIRC,malloc
使用 mmap
进行大量分配。【参考方案2】:
我找到了这个
Inact_dirty:Dirty 表示“可能需要写入磁盘或交换”。需要 更多的工作是免费的。示例可能是尚未写入的文件 到还。它们不会过早地写入内存以保持 I/O 关闭。例如,如果您正在编写日志,最好 等到您准备好完整的日志后再将其发送到磁盘。
取自这里:http://www.redhat.com/advice/tips/meminfo.html
我猜这很像 I/O 缓冲区上的脏位? 我的意思是说这个缓冲区应该写在磁盘上,因为它已经被修改了(在 linux 上)。
你有一个类似的问题:https://unix.stackexchange.com/questions/33381/getting-information-about-a-process-memory-usage-from-proc-pid-smaps
【讨论】:
感谢您的回答。它有点帮助,但关键是我没有执行任何 I/O 操作......你知道脏内存增长的任何其他原因吗? @LuisAntonioBotelhoO.Leite - 在大多数“真实”系统上,所有堆都是“虚拟”的,可以写入磁盘以释放 RAM 用于其他目的。您的“脏内存”正在增长,因为应用程序尚未达到稳定状态。 @LuisAntonioBotelhoO.Leite - “稳态”是虚拟内存系统中的一种情况,其中每个类别中的页面数量往往相对稳定,因为转换到类别的速率大致匹配评分。当一个进程运行足够长的时间而不改变其执行模式时(并且当系统工作负载的其余部分也相当稳定时),就会发生这种情况。在这种情况下进程需要的页数称为“工作集”。 @LuisAntonioBotelhoO.Leite - 一旦写入堆位置,进程分配的每个堆页面都将被标记为“脏”。如果它被写入然后很长时间没有被引用,操作系统会将它“刷新”到磁盘以释放 RAM 用于其他用途。如果它被引用,“falted on”,并且读回它不会是“脏的”,除非并且直到它再次被修改。 “脏”页面绝对没有问题——它们表明进程正在工作,因此页面包含未反映在磁盘映像中的更改。 @LuisAntonioBotelhoO.Leite - 不,脏内存正在增长,因为您的程序正在更改堆中的值。或以其他方式更改存储页面。操作系统并不急于写出更改的页面,因为您会不断地一次又一次地更改它们,因为您分配新对象并删除它们,因此如果一个页面被写出,它将立即再次变得“脏”。拥有“脏”页没有任何问题!以上是关于什么是脏私有内存?的主要内容,如果未能解决你的问题,请参考以下文章