mmap和内存使用情况

我正在写一个程序,从networking接收大量的数据(不同大小),处理它们并将它们写入内存。 由于某些数据块可能非常大,我目前的做法是限制使用的缓冲区大小。 如果一个块大于最大缓冲区大小,我将数据写入一个临时文件,稍后读取文件块进行处理和永久存储。

我想知道这是否可以改善。 我一直在阅读有关mmap的一段时间,但是我不是百分之百确定它是否能帮助我。 我的想法是使用mmap来读取临时文件。 这有什么帮助吗? 我关心的主要问题是偶尔的一大块数据不应该填满我的主内存,导致所有的内容都被换出。

另外,你认为临时文件的方法是有用的吗? 我甚至应该这样做,或者,我应该相信linux内存pipe理器为我做这个工作吗? 或者我应该干点什么?

Solutions Collecting From Web of "mmap和内存使用情况"

Mmap可以在某些方面帮助你,我会用一些假设的例子来解释:

首先,假设你的内存不足了,你的应用程序有一个100MB的malloc,内存占用了50%的内存,这意味着操作系统必须写50MB的交换文件,如果你需要读回来,你已经写了,占用,然后再读回50MB的交换文件。

如果内存只是被mmap化了,操作系统将不会把这段信息写到交换文件(因为它知道这个数据和文件本身是一样的),相反,它只会抓取50MB的信息(再一次:假设你现在没有写任何东西)就是这样。 如果您需要再次读取内存,操作系统将不会从交换文件中提取内容,而是从原始文件中取出内容,所以如果有其他程序需要50MB的交换空间,则它们可用。 另外,根本没有交换文件操作的开销。

假设你读了一个100MB的数据块,根据最初的1MB的头文件数据,你想要的信息位于偏移量75MB,所以在1〜74.9MB之间不需要任何东西! 你已经读了它,只是为了让你的代码更简单。 使用mmap,你只能读取你实际访问的数据(四舍五入,或操作系统页面大小,大部分是4kb),所以它只能读取第一个和第75个MB。 我认为做一个比mmaping文件更简单,更有效的避免磁盘读取的方法是非常困难的。 如果由于某种原因需要37MB的数据,您可以使用它! 因为整个文件可以在内存中访问(当然受限于进程的内存空间),所以不需要再次进行映射。

所有mmap的文件都是由自己备份的,而不是由交换文件来备份,交换文件是用来授予没有文件备份的数据,通常是数据malloc或数据由文件备份,但在程序实际通过msync调用通知操作系统这样做之前,它已被修改,并且[不能/不应该]被写回。

注意,你不需要映射整个文件在内存中,你可以从任何地方(第6个参数 – “off_t偏移量”)开始映射任何数量(2nd arg是“size_t length”),但是除非你的文件可能即使系统只包含了64MB的物理内存,也可以安全地映射1GB的数据,但这是为了阅读,如果你打算写作,那么你应该更保守,只绘制你需要的东西。

映射文件可以帮助你简化代码(你已经拥有内存中的文件内容,可以使用,因为它不是匿名内存,所以内存更少),而且速度更快(只能读取程序访问的数据)。

使用大文件的mmap的主要优点是在两个或多个文件之间共享相同的内存映射:如果您使用MAP_SHARED mmap映射,那么对于将使用数据并保存内存的所有进程,它只会被加载到内存中一次。

但是AFAIK,mmap将整个文件映射到内存中( 在这里你可以找到mmap如何比文件大于物理mem +交换空间的例子),所以如果你从一个进程访问文件,它不会帮助你的物理内存消耗。

我相信mmap不需要同时在内存中存储所有的数据 – 它使用页面缓存来保持最近使用的页面在内存中,其余的在磁盘上。

如果您一次只读一个块,使用临时文件可能不会帮助您,但是如果您正在使用多个线程,进程或使用select / poll同时读取多个块,那么可能会发生这种情况。