首先,提供一些有用的背景信息:我有一个基于C ++的服务器进程,该进程在嵌入式ARM / Linux计算机上运行。它工作得很好,但是作为其操作的一部分,它会创建一个相当大的固定大小的临时/非持久状态信息数组(例如,数十到数百兆字节),当前将其保存在堆中,并且可以访问和/或不时更新该数据。
我正在研究可以扩展的范围,而我遇到的一个问题是最终(当我通过使服务器的配置越来越大来对其进行压力测试时),此数据结构变得足够大,可以导致内存不足的问题,然后出现OOM杀手er,随之而来的是普遍的不满。请注意,Linux的嵌入式配置未启用交换功能,因此我无法(轻松地)启用交换分区。
关于如何改善此问题的一个想法是,在计算机的本地闪存分区上分配这个大数组,而不是直接在RAM中分配,然后使用mmap()使它在服务器进程中看起来像仍然在内存。这样可以大大减少RAM的使用,我希望Linux的文件系统缓存可以掩盖由此产生的大部分性能成本。
我唯一真正关心的是文件管理-特别是,我想避免任何机会用“孤立的”后备存储文件(即已不再存在进程的旧文件,但该文件仍然存在,因为其创建过程崩溃或由于其他错误而忘记了在退出时将其删除)。我还希望能够在同一台计算机上同时运行服务器的多个实例,而各实例之间不会互相干扰。
我的问题是,Linux是否有内置的工具来处理这种用例?我特别想出一种标记文件(或mmap()句柄或类似文件)的方法,以便在创建进程的文件退出或崩溃时,操作系统自动删除该文件(类似于Linux已经自动删除该文件的方式)当进程退出或崩溃时,恢复由进程分配的所有RAM。
或者,如果Linux没有任何内置的auto-temp-file-cleanup功能,人们是否有“最佳实践”来确保大型临时文件不会因驱动器耗尽而结束意外地变得持久?
请注意,由于/ tmp使用RAM磁盘,因此AFAICT仅仅将文件放在/ tmp中不会帮到我,因此与简单地分配进程内堆存储相比,它没有给我任何RAM使用优势。 / p>
答案 0 :(得分:3)
是的,我一直在这样做...
work1_start work1_end work2_start work2_end duration
2018-09-06 08:00:00 2018-09-06 08:00:00 2018-09-06 09:30:00 2018-09-06 10:30:00 90
2018-09-06 09:30:00 2018-09-06 10:30:00 2018-09-06 11:00:00 2018-09-06 13:00:00 30
2018-09-06 11:00:00 2018-09-06 13:00:00 2018-09-06 14:00:00 2018-09-06 15:00:00 60
2018-09-06 14:00:00 2018-09-06 15:00:00 2018-09-06 17:00:00 2018-09-06 17:00:00 120
文件,open
,使用unlink
或(更好)ftruncate
使其大小正确,然后将posix_fallocate
与{{ 1}}将其映射到您的地址空间。然后,您可以根据需要立即mmap
描述符;内存映射本身将保留文件。
为了提高速度,您可能会发现要帮助Linux管理其页面缓存。您可以将MAP_SHARED
与close
一起使用,以建议内核分页数据,而posix_madvise
则建议内核释放页面。
您可能会发现last不能以您想要的方式工作,特别是对于脏页。您可以使用POSIX_MADV_WILLNEED
显式控制刷新到磁盘。 (尽管在这种情况下,您将需要保持文件描述符打开。)
除了特定于Linux的POSIX_MADV_DONTNEED
,所有这些都是POSIX的完美标准。
答案 1 :(得分:2)
是,您创建/打开文件。然后,按文件名remove()
{1>}。
该文件仍将由您的进程打开,您可以像打开任何文件一样对其进行读取/写入,并且在打开该文件的进程退出时它将消失。
我相信此行为是posix强制执行的,因此它可以在任何类似unix的系统上使用。即使进行了硬重启,该空间也将被回收。
答案 2 :(得分:1)
我相信这是特定于文件系统的,但是大多数Linux文件系统都允许删除打开的文件。该文件将一直存在,直到关闭文件的最后一个句柄为止。我建议您打开文件,然后立即将其删除,并且由于任何原因退出进程时,它将自动将其清除。
有关更多详细信息,请参见这篇文章:What happens to an open file handle on Linux if the pointed file gets moved, delete