我有 1TB 的 RAM,其中 900GB 需要在进程中分配和使用(我对硬件有完全的控制权,并且我正在裸机上工作)。我使用(私有、匿名)分配 900GB 内存mmap()
,然后用于madvise()
在 Fedora 37 上设置透明大页。然后这 900GB 线性填充数据。
这不是实际的程序,但它给出了内存访问类型的想法:
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <sys/mman.h>
int main() {
const uint64_t n = 900000000000ULL;
char *p = (char *)mmap(NULL, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
madvise(p, n, MADV_HUGEPAGE);
for(uint64_t i = 0; i < n; i++) p[i] = i; // Which data is immaterial
}
我可以看到系统随着更多内存的访问而分配透明大页面。然而,一旦我分配当前使用的 buff/cache 内存(例如 300GB),进程就会被猛烈终止;连炮弹都杀了,也没有报告信号。/var/log/messages
或上没有消息dmesg
(例如,OOM 杀手似乎没有问题)。
这不是一个过度使用的问题:它与vm.overcommit_memory = 1
.我什至尝试vm.vfs_cache_pressure = 1000
强制 Linux 释放缓冲区/缓存页面。没有结果。
此外,如果我mmap()
用标准替换调用,malloc()
一切都会顺利进行:随着进程接触越来越多的内存,缓冲/缓存内存会逐渐释放。这具体是透明大页面的问题(内核错误?)。
目前,我正在启动程序之前执行此操作echo 3 > /proc/sys/vm/drop_caches
,通过这种方式,我可以分配和使用几乎所有具有透明大页面的内存,但这不是执行此操作的正确方法。
有什么建议么?