是否可以强制 Linux 在释放后使虚拟内存失效
Is it possible to force Linux to invalidate virtual memory after free
在Windows上,我注意到尝试取消引用指向最近释放的内存的指针会导致崩溃,Visual Studio捕获了该内存无效。这是意料之中的。但是,执行相同的应用程序和代码路径导致取消引用指向最近释放的内存的指针不会立即导致 Linux 崩溃。这向我表明,Linux 内核(或 GNU C++运行时)不会很快使释放的内存失效,即使在调试版本中也是如此。应用程序崩溃需要更长的时间。是这样吗?如果是这样,我可以强制更快地取消映射内存吗?如果不是,那又是怎么回事呢?
你试过 http://valgrind.org/吗?其目的是帮助跟踪您所描述的问题。
new
/delete
的大多数实现不返回内存立即进入系统,或者至少不要返回更小块。 我很惊讶你的代码崩溃了窗口只需取消引用指向内存的指针;你是确保您没有做更多的事情(例如,使用您读取的值通过指针)。
街区有多大? 许多实现使用不同的策略取决于块的大小,并将免费非常大的块立即。 (IIRC,Linux将做一个mmap
对于非常大的块,立即取消映射你释放它。 当然,如果在释放并取消引用指针,有可能地址位于新分配的空间中,它不会崩溃。
最后:映射的粒度是页面,而你不能期望分配器为每个分配器阻塞一个完整的页面分配,只是为了让它可以使内存失效立即解除分配。 (一个页面可能至少是 4K,而且您不想每次都丢失 4K 地址空间分配 16 个字节。 缺少跟踪所有内存访问(如ValGrand 或 Purify),并且运行速度慢得多,唯一的替代方法是使用垃圾回收,以确保只要有指向内存的指针,就不会重新分配内存,并在释放时完全覆盖它(即在 delete
或 free
),其值在使用时可能会导致问题(0xDEADBEEF
,或类似的东西)。 即便如此,你也是不能真正保证你会崩溃——0xDEADBEEF
可以是您认为您正在阅读的内容的有效值。 (但是这个确实允许例如在构造函数中设置标志,重置它在析构函数中,并在每个函数中对其进行测试。 对于代码这必须是积极的防御。
- 为什么瓦尔格林德在不释放恶意内存后没有报告任何问题?
- 了解 Linux 虚拟内存:valgrind 的 massif 输出显示了有和没有 --pages-as-heap 的主要差异
- 释放动态内存时C++错误
- 引用释放的内存是未定义的行为吗?
- 我是否访问了已释放的内存,或者在这种情况下DrMemory报告不正确?
- 在C++应用程序中使用 Tensorflow:如何释放 GPU 内存
- 指向数组unique_ptr在调用 release() 后会自动释放动态内存,这是真的吗?
- 我可以使用哪种数据结构来释放连续内存中的内存?
- 为什么我只能在 4 GB 的虚拟内存空间上分配 2 GB?
- AWS pandas 安装出现错误:虚拟内存已耗尽:无法分配内存
- 动态使用返回的数组,如何释放其内存
- 如何判断虚拟内存页是否已锁定
- 如何使用一个 VirtualFree 调用删除多个相邻的虚拟内存分配?
- 如何在函数结束时有效地释放矢量内存
- 对等方断开连接后未释放 SSL 内存
- 如果在构造函数中发生异常,如何释放动态内存
- 如何找到写入释放的内存(堆损坏)?
- Arduino没有释放RAM内存
- 是否可以强制 Linux 在释放后使虚拟内存失效
- 释放 Windows 上C++ 'new'保留的虚拟内存