C 使用结构池正确处理内存

C 使用结构池正确处理内存,c,memory,memory-management,pool,C,Memory,Memory Management,Pool,我有一个有三个结构池的程序。对于它们中的每一个,我使用一个已使用结构的列表,另一个用于未使用的结构。在执行过程中,程序使用结构,并根据需要将它们返回到池中。此外,还有一个垃圾收集器来清理“僵尸”结构并将其返回到池中 在执行开始时,虚拟内存(如预期的那样)显示大约10GB*的已分配内存,并且随着程序使用池,RSS内存会增加 虽然已使用的节点返回池中,标记为未使用的节点,但RSS内存不会减少。我希望如此,因为操作系统不知道我在用内存做什么,也无法注意到我是在真正使用它们还是在管理一个池 我想做的是在

我有一个有三个结构池的程序。对于它们中的每一个,我使用一个已使用结构的列表,另一个用于未使用的结构。在执行过程中,程序使用结构,并根据需要将它们返回到池中。此外,还有一个垃圾收集器来清理“僵尸”结构并将其返回到池中

在执行开始时,虚拟内存(如预期的那样)显示大约10GB*的已分配内存,并且随着程序使用池,RSS内存会增加

虽然已使用的节点返回池中,标记为未使用的节点,但RSS内存不会减少。我希望如此,因为操作系统不知道我在用内存做什么,也无法注意到我是在真正使用它们还是在管理一个池

我想做的是在任何时候强制未使用的内存返回到虚拟内存,例如,当RSS内存增加到xGB以上时

给定内存指针,有没有办法标记一个内存区域以将其放入虚拟内存?我知道这是操作系统的责任,但也许有办法迫使它

也许我不该关心这个,你觉得呢

提前谢谢

  • 注1:该程序用于高性能计算,这就是为什么它使用了这么多内存
对于一些文件,我提供了池使用情况与内存使用情况的图片。正如您所看到的,池使用率的突然下降是由于垃圾收集器造成的,我希望看到的是,内存使用率的下降


只要您是通过mmap而不是通过malloc分配内存,就可以这样做。您希望将函数与
POSIX\u MADV\u DONTNEED
参数一起使用

只需记住在再次使用它们之前,使用POSIX_MADV_WILLNEED运行madvise,以确保它们背后确实有内存

这实际上并不能保证页面将被交换出去,但给了内核一个强烈的提示,当内核有时间时可以这样做。

Git 2.19(2018年第3季度)提供了一个struct的内存池示例,使用而不是
malloc

对于大型树,索引需要保存堆上分配的许多缓存项。
这些缓存项现在从专用内存池中分配出来,以分摊开销

参见,,,(2018年7月2日)作者。 (于2018年8月2日被合并)

block alloc
:从
mem\u池中分配缓存项
从磁盘读取大型索引时,一部分时间主要用于
malloc()
调用。
这可以通过分配一大块内存并通过内存池自行管理来缓解

此更改将缓存项分配移动到内存池的顶部

设计:
index\u状态
struct将获得关联的
内存池
的概念,缓存项将从该池分配。
在从磁盘读取索引时,我们有关于条目数及其大小的信息,这些信息可以指导我们决定初始内存分配的大小。
当索引被丢弃时,关联的
内存池也将被丢弃-因此
缓存项的生存期
与分配给它的
索引状态
的生存期相关联

对于拆分索引,遵循以下规则。
首先,定义了一些术语:

术语:
  • the_index
    ”:表示索引的逻辑视图
  • split_index
    ”:表示“基本”缓存项。 从拆分索引文件中读取
u索引
”可以引用单个
split\u索引
,也可以引用
split\u索引
中的
cache\u条目
<代码>分割索引
之前,将丢弃该索引。
这意味着,当我们在存在拆分索引的情况下分配
缓存项时,我们需要从
拆分索引的内存池中分配项

这允许我们遵循这样的模式,即
索引可以引用
分割索引中的缓存项,并且
缓存项在仍被引用时不会被释放

管理临时缓存\u条目结构: 缓存项通常分配给索引,但情况并非总是如此。有时会分配缓存项,因为这是现有的
签出\u项
功能所使用的类型。
因此,现有代码需要处理与索引/内存池关联的缓存项,以及那些仅暂时存在的缓存项。
围绕如何处理这一问题,考虑了几种策略

选择的方法: 在
缓存项
类型中添加了一个额外字段,以跟踪缓存项是否从内存池分配。
这是当前的
int
字段,因为现有字段中没有更多可用位
ce\u标志
位字段。
如果/当需要更多位时,此新字段可以转换为适当的位字段

我们决定对已知内存池区域进行跟踪和迭代 不如添加一个额外的字段来跟踪此状态


您可能需要说明您的平台/操作系统,因为这是高度依赖于系统的。我在Linux 2.6.32(70GB内存)和Mac OS X Mavericks(16GB内存)中进行了测试。我不明白为什么您要强制系统将您的结构标记为“免费”,因为您可以在空闲时在程序中重复使用它。这是我关心的问题之一。我应该在乎吗?但是,无论如何,有没有办法强迫它呢?假设另一个进程正在使用该机器,并且没有足够的内存用于这两个进程。如何辨别操作系统中的哪个进程