【发布时间】:2019-08-26 18:46:18
【问题描述】:
这几天我了解到内存过度使用的问题(当内存过度使用被激活时,通常是默认设置),这基本上意味着:
void* p = malloc(100);
操作系统为您提供 100 个从进程的(虚拟)地址空间中获取的连续(虚拟)地址,其总范围由操作系统定义。由于该内存区域尚未初始化,因此从系统范围的角度来看,它不算是占用的存储空间,因此除了消耗您的虚拟地址之外,它只是一个纯粹的抽象。
memset(p, 0, 5);
它使用前 5 个字节,因此从操作系统的角度来看,您的进程现在占用了 5 个额外字节,因此系统的可用存储空间减少了 5 个字节。您还有 95 字节的未初始化存储空间。
只有当每个进程的合并占用存储(初始化)超出操作系统可以容纳的容量时,系统才会崩溃或开始杀死进程。
如果我在这方面的理解是正确的,有没有办法在完成后“反”初始化内存区域,以增加系统范围的可用空间,而不会丢失请求的地址区域通过malloc 或aligned_malloc(这样您就不会随着时间的推移增加碎片)?
这个问题的目的更多的是理论而不是实际,而不是关于实际“释放内存”,而是关于在保留已分配的虚拟地址的同时释放内存。
请求虚拟地址和占用存储的区别来源:https://www.win.tue.nl/~aeb/linux/lk/lk-9.html#ss9.6
PD:知道 Linux 可以满足我的好奇心,我很好。
【问题讨论】:
-
你不需要关心。相信操作系统会调出最近未使用的内存。
-
只要你
delete或free内存你不再使用,你很少需要关心。操作系统大部分时间都会做正确的事情。如果你确实实际上必须关心,那么禁用过度提交是一个选项,在 C++ 中你可以捕获std::bad_alloc。 -
看看 Linux
madvise(MADV_DONTNEED)、madvise(MADV_FREE)或posix_madvise(POSIX_MADV_DONTNEED)是否按照您的意愿行事。但不要干涉 malloced 内存!仅在您手动拥有mmap-ed 的页面上使用 madvise! -
@igor,国际海事组织,你刚刚交给了一个人,并用超动力的枪,这样他们就可以把自己的脚炸掉。
-
@Jeffrey,我认为吹虚拟脚没有害处。这是获得经验的一种方式。
标签: c++ initialization storage memory-overcommitment