fwrite 消耗所有 MemFree,fflush 不起作用?

Posted

技术标签:

【中文标题】fwrite 消耗所有 MemFree,fflush 不起作用?【英文标题】:fwrite consuming all MemFree, fflush not working? 【发布时间】:2017-06-04 15:19:21 【问题描述】:

我们有一个连接到非常快的 10TB raid 0 jbod 的数据捕获系统。

我们以大约 1.25 GB/s 的速度接收 4 MiB 数据缓冲区,这些缓冲区被写入使用 fopen 打开的顺序文件,分配了 10 GiB,并使用 fwrite 写入。每 10 GiB 我们 fflush 然后 fallocate 再获得 10 GiB。最后用 fclose 完成捕获后关闭。

问题在于,在捕获过程中,我们可以看到 /proc/meminfo MemFree 下降,并且 Cached 上升——即 fflush 似乎什么也没做。这一直持续到我们在系统中有大约 200 MiB MemFree,现在数据速率变得非常尖峰,这导致我们的捕获失败。

我们希望调用 fflush 时峰值会下降到 10 GiB 左右,但它似乎没有任何作用。在我们调用 fclose 之前文件不会被刷新。

这种行为有什么原因吗?使用 setvbuf(hFile, NULL, _IONBF, 0) 似乎也没有任何效果。

【问题讨论】:

我不确定具体问题是什么,但您可能只想使用较低级别的调用 openwrite。您需要使用fopenfwrite 有什么特别的原因吗?另外,fallocate 有什么好处?写入文件时将分配空间。 AndySchweig 使用打开/写入/关闭也会发生该行为。 (我认为 fallocate 背后的想法是提高性能。) 显而易见的问题:您确定您的磁盘阵列可以写入 1.25 GB/秒吗? @duskwuff 是的,2x 1.25 GB/s 在Windows下已经成功使用了。 既然你在管理自己的缓冲区,是否可以使用 O_DIRECT 进行写入?这样,您的操作系统在写入时不会使用其缓冲区缓存来保留内存中的数据? fwrite 也在自己缓冲。所有保存数据的缓冲区可能存在资源争用。当您达到内存使用上限时,您最终会丢失捕获,因为您的操作系统和/或 stdio 正忙于管理缓冲区。 【参考方案1】:

当您看到可用内存下降时,表明您的操作系统正在写入其缓冲区缓存(本质上是所有可用内存)。此外,stdio 的fwrite() 正在自行缓冲。因此,发生了一些资源争用。当您的操作系统达到可用内存的上限时,这种资源争用会导致写入速度变慢和内存利用率高。瓶颈会导致您错过数据捕获。

由于您正在管理自己的缓冲区,因此可以使用 write()O_DIRECT 来避免所有这些缓冲。

【讨论】:

以上是关于fwrite 消耗所有 MemFree,fflush 不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 fwrite 将结构的字符串成员写入文件?

fsync与fflush的关系和区别

fsync与fflush的关系和区别

使用来自多个进程的 fseek/fwrite 写入文件的不同区域?

C 语言文件操作 ( fwrite 函数 )

MATLAB fwrite 怎么换行