是否可以强制 Linux 在释放后使虚拟内存失效

Is it possible to force Linux to invalidate virtual memory after free

本文关键字:释放 虚拟内存 失效 Linux 是否      更新时间:2023-10-16

在Windows上,我注意到尝试取消引用指向最近释放的内存的指针会导致崩溃,Visual Studio捕获了该内存无效。这是意料之中的。但是,执行相同的应用程序和代码路径导致取消引用指向最近释放的内存的指针不会立即导致 Linux 崩溃。这向我表明,Linux 内核(或 GNU C++运行时)不会很快使释放的内存失效,即使在调试版本中也是如此。应用程序崩溃需要更长的时间。是这样吗?如果是这样,我可以强制更快地取消映射内存吗?如果不是,那又是怎么回事呢?

你试过 http://valgrind.org/吗?其目的是帮助跟踪您所描述的问题。

new/delete的大多数实现不返回内存立即进入系统,或者至少不要返回更小块。 我很惊讶你的代码崩溃了窗口只需取消引用指向内存的指针;你是确保您没有做更多的事情(例如,使用您读取的值通过指针)。

街区有多大? 许多实现使用不同的策略取决于块的大小,并将免费非常大的块立即。 (IIRC,Linux将做一个mmap对于非常大的块,立即取消映射你释放它。 当然,如果在释放并取消引用指针,有可能地址位于新分配的空间中,它不会崩溃。

最后:映射的粒度是页面,而你不能期望分配器为每个分配器阻塞一个完整的页面分配,只是为了让它可以使内存失效立即解除分配。 (一个页面可能至少是 4K,而且您不想每次都丢失 4K 地址空间分配 16 个字节。 缺少跟踪所有内存访问(如ValGrand 或 Purify),并且运行速度慢得多,唯一的替代方法是使用垃圾回收,以确保只要有指向内存的指针,就不会重新分配内存,并在释放时完全覆盖它(即在 deletefree ),其值在使用时可能会导致问题(0xDEADBEEF,或类似的东西)。 即便如此,你也是不能真正保证你会崩溃——0xDEADBEEF可以是您认为您正在阅读的内容的有效值。 (但是这个确实允许例如在构造函数中设置标志,重置它在析构函数中,并在每个函数中对其进行测试。 对于代码这必须是积极的防御。