强制释放内存到操作系统
Force memory release to the OS
我有一个应用程序,需要大约20 MB的内存。在一个很少使用的算法中,它(std::vector)临时分配250 MB。在释放后,系统监视器仍然显示这种用法。如何将内存释放回系统?
你不能,也不应该。
虚拟内存分配是复杂的,不能通过简单地观察System Monitor中的数字来充分理解。它可能看起来好像一个进程使用了比它应该使用的更多的内存,但这只是虚拟内存寻址工作方式的产物。
请放心,如果您正确地释放了该内存,并且操作系统确实需要它,它将被重新分配。
这里唯一真正可行的点是停止使用系统监视器,好像它是一个准确的测量物理内存在使用你的进程!
使用mmap()或VirtualAlloc()来分配和释放内存。这将立即返回操作系统。
为了与std::vector一起使用,你需要为它提供一个std::allocator。您可能会发现,手工滚动自己的vector w/location和new和直接析构函数调用更容易。
通常系统堆分配器会为你正确处理这个;然而,看起来你发现了一个情况,他们没有。
这不是虚拟内存和堆管理器的工作方式(至少在Windows上不是)。
在Windows上,你有两个级别的内存管理。内存管理的最基本形式是由操作系统完成的。在操作系统中,您可以通过VirtualAlloc()
请求内存。VirtualAlloc()
以粒度的倍数提供内存。粒度的典型值是64 kB。
正确理解:如果您从VirtualAlloc()
请求1字节,您可以这样做。但是:你会浪费很多内存,因为函数返回的块至少有64 kB。
你可能会问:"WTF?为什么?"。想象一下,操作系统将能够跟踪您分配的每个字节。存储分配的每个字节的地址将需要比实际可用内存更多的内存。所以必须有一个妥协。
这就是为什么Windows有另一个机制:Windows堆管理器。Windows堆管理器占用64 kB的大块虚拟内存(通过VirtualAlloc()
,同样的调用),然后为您做一些聪明的管理。
如果你从Windows堆管理器请求1个字节,你得到一个指向1个可用字节的指针。在那个内存位置周围会有一些开销,对此我不想深入讨论。这将需要解释术语堆,段,块,预分配元数据和后分配元数据。你可以在Mark Russinovich的《Windows内部》一书中了解到所有这些。
可以这样考虑:堆管理器将进一步将64kb块分解为不同大小的分配区域。在这个64kb块的某个地方,它将存储如何使用内存的信息。
如果您free()
或delete
一个或几个指针,这些内存很可能仍然没有释放。a)它仍然包含Windows堆管理器的管理结构,b)它可能包含至少一个指针。
因此,即使该内存区域中只剩下1个指向1字节的指针,Windows堆管理器也无法将64kb的块返回给操作系统。
其他需要考虑的事情(但我不确定):Windows堆管理器可能不会在每个free()
或delete
检查64 kB块的所有内存是否被释放。a)计算可能会花费很长时间(特别是对于像c++这样的语言),b)在不久的将来,无论如何,您可能会将malloc()
或new
作为一个字节。那么,堆管理器为什么要将它已经拥有的内存返回给操作系统呢?
以上所有内容都独立于分页进程。未使用的内存可以按页大小的块进行分页,通常为4 kB。"页面out"
表示"写入磁盘到pagefile.sys
"。为什么这很重要?这意味着虚拟内存不必使用快速而有价值的物理RAM。
你释放了250mb ?让操作系统决定它是否可以在物理RAM中保留这250 MB,或者是否将其分页。如果您的应用程序请求新的虚拟内存,它可能会受益于这个事实,即它恰好是免费的(即不调用VirtualAlloc()
)。
- 为什么 free() 函数不将内存返回给操作系统?
- 检测到由于操作系统内存不足而导致子进程终止
- 如果操作系统未清除内存泄漏,则在程序完成后内存泄漏是否仍然存在?
- 支持 CUDA 统一内存的系统分配器的操作系统版本
- 为什么操作系统不拒绝此程序的内存?
- 操作系统对内存访问违规的处理与内存写入违规的处理
- 如何确保 std::vector 分配的内存在解除分配后返回给操作系统
- 依赖于操作系统的C++内存泄漏
- 如何防止操作系统刷新视频内存
- 是否有任何操作系统允许将内存从一个地址移动到另一个地址而不进行物理复制?
- 分配的内存可以在需要时由操作系统释放
- 在64位操作系统中运行的32位应用程序可以寻址的不同内存的数量是多少?
- 强制释放内存到操作系统
- 内存映射一个巨大的文件在32位软件运行在64位操作系统
- 在C/ c++中通过int main()返回0,在任何操作系统上,清除程序在任何(RAM,缓存或任何…)内存中使用的所有
- 如何比较2D矢量大小与操作系统内存地址限制
- 为什么操作系统分配的内存比小型可执行文件所需的要多
- 在大量使用unique_ptr语言 - c++后释放内存给操作系统
- mmap小尺寸内存,当munmap为glibc时,会将映射内存释放到操作系统
- 当我们使用new来分配内存时,操作系统做了什么样的簿记?