Linux non-persistent backing store for mmap()
Linux non-persistent backing store for mmap()
首先,一些激励性的背景信息:我有一个基于C++的服务器进程,该进程在基于ARM/Linux的嵌入式计算机上运行。 它运行良好,但作为其操作的一部分,它会创建一个相当大的固定大小的临时/非持久状态信息数组(例如数十到数百兆字节(,它当前将其保存在堆中,并且它会不时访问和/或更新该数据。
我正在调查我可以在多大程度上扩展事情,我遇到的一个问题是,最终(当我通过使其配置越来越大来对服务器进行压力测试时(,这种数据结构变得足够大,导致内存不足问题,然后 OOM 杀手出现,随之而来的是普遍的不满。 请注意,Linux 的这种嵌入式配置没有启用交换,我无法(轻松(启用交换分区。
关于如何改善这个问题,我有一个想法是将这个大数组分配给计算机的本地闪存分区,而不是直接在 RAM 中,然后使用 mmap(( 使服务器进程看起来就像它仍在 RAM 中一样。 这将大大减少RAM的使用,我希望Linux的文件系统缓存能够掩盖大部分由此产生的性能成本。
我唯一真正关心的是文件管理 - 特别是,我想避免任何用"孤儿"备份存储文件填充闪存驱动器的机会(即进程不再存在的旧文件,但文件仍然存在,因为它的创建过程崩溃或由于其他错误忘记在退出时删除它(。 我还希望能够在同一台计算机上同时运行服务器的多个实例,而这些实例不会相互干扰。
我的问题是,Linux是否有任何内置的工具来处理这种用例? 我特别想象某种方法来标记文件(或 mmap(( 句柄或类似(,以便当创建进程的文件退出或崩溃时,操作系统会自动删除该文件(类似于 Linux 已经自动恢复进程分配的所有 RAM 的方式,当进程退出或崩溃时(。
或者,如果 Linux 没有任何内置的自动临时文件清理功能,人们是否使用"最佳实践"来确保大型临时文件不会因无意中变得持久而最终填满驱动器?
请注意,AFAICT 简单地将文件放在/tmp 中对我没有帮助,因为/tmp 使用的是 RAM 磁盘,因此与简单地分配进程内堆存储相比,它不会给我带来任何 RAM 使用优势。
是的,我一直这样做...
open
文件,unlink
它,使用ftruncate
或(更好的(posix_fallocate
使其大小合适,然后将mmap
与MAP_SHARED
一起使用以将其映射到地址空间。然后,如果需要,您可以立即close
描述符;内存映射本身将保留文件。
为了提高速度,您可能会发现您想帮助 Linux 管理其页面缓存。您可以将posix_madvise
与POSIX_MADV_WILLNEED
一起使用来建议内核对数据进行页面处理,POSIX_MADV_DONTNEED
建议内核释放页面。
您可能会发现最后一个不能按您想要的方式工作,尤其是对于脏页面。您可以使用sync_file_range
显式控制刷新到磁盘。(尽管在这种情况下,您需要保持文件描述符打开。
所有这些都是完全标准的POSIX,除了Linux特定的sync_file_range
。
是的,您创建/打开文件。然后,按文件名remove()
文件。
该文件仍将由您的进程打开,您可以像任何打开的文件一样读取/写入它,并且当打开文件的进程退出时,它将消失。
我相信这种行为是由posix强制要求的,所以它可以在任何类似Unix的系统上运行。即使在硬重启时,空间也会被回收。
我相信这是特定于文件系统的,但大多数 Linux 文件系统允许删除打开的文件。该文件将仍然存在,直到关闭它的最后一个句柄。我建议您打开该文件,然后立即将其删除,当您的进程因任何原因退出时,它将自动清理。
有关更多详细信息,请参阅这篇文章:如果指向的文件被移动,Linux 上的打开文件句柄会发生什么情况,删除
- "error: no matching function for call to"构造函数错误
- 表示"accepting anything for this template argument" C++概念的通配符
- 如何在C++中从两个单独的for循环中添加两个数组
- 在Linux for Windows上编译C++代码时出错
- 调用专用模板时出错"no matching function for call to [...]"
- 为什么我的for循环不能正确获取argv
- 为什么我不能在 FOR LOOP 中使用 i/10,C++?
- 如何将PERF_AMPLE_READ与mmap一起使用
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- 在基于范围的for循环中使用结构化绑定声明
- 通过for循环使用用户输入填充列表
- 使用for循环检查数组中的重复项
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 正在使用for循环创建QScatterSerie
- Python中的for循环与C++有何不同
- std::memory_order for std::atomic:<T>:wait
- 在更改for循环的第三部分后,未使用for循环结果
- Linux non-persistent backing store for mmap()
- 在 mmap'ed 区域上使用 memcpy 崩溃,for 循环不会