14

I'm using a FileSystemWatcher to monitor changes in a folder, but as soon as I have more than a few hundred modifications in a short time, I miss some of them because the internal buffer overflows. So I want to increase the InternalBufferSize (I know it won't really solve the problem, but it will make it less likely to occur), but I see this warning in the documentation:

However, increasing buffer size is expensive, because it comes from non-paged memory that cannot be swapped out to disk, so keep the buffer as small as possible.

So my question is: does it really matter? Most computers today have at least 1GB of RAM, so it seems to me that if I set the buffer size to 1MB (instead of the default 8KB), it shouldn't really matter if 1MB can't be swapped out to disk. Or am I missing something? I don't know much about low level stuff such as paged/non-paged memory, so I'm not sure what the impact would be...

4

3 回答 3

23

分配缓冲区的内存当然是宝贵的资源。Windows 不能很好地处理耗尽内存池,驱动程序将开始随机失败。池的大小是动态设置的(但可以更改)并且取决于可用 RAM 的数量。

FSW 要求的默认缓冲区大小为 8192 字节。在现代机器上不多。底层的 winapi 函数不允许你请求超过 64KB。一个条目是缓冲区是 12 字节加上文件路径的长度乘以 2。所以更糟糕的情况是在缓冲区用完之前有 8192 / (12 + 260*2) = 15 个通知。这在大多数情况下应该可以正常工作,除非您监控整个驱动器或您正在观看的目录中有非常高的磁盘流量。在这种情况下,要求更大的缓冲区是公平的。没有黄金公式,一定要实现 FileSystemWatcher.Error 事件,这样你就知道你遇到了缓冲区问题。

在大多数实际情况下,您需要仔细处理 FSW 事件。当进程仍然锁定文件时,它们将被引发。因此,打开或复制文件之类的操作很麻烦。您可以通过将通知放在线程安全队列中并使用另一个线程尝试获取文件上的锁来处理这个问题,如有必要,请重复。这样的队列现在也是自动快速清空缓冲区的一个很好的方法。你现在唯一需要注意的是队列不会超过合理的比例,这会使你的程序因 OOM 崩溃。

于 2012-12-17T16:06:35.683 回答
3

考虑一个消费者生产者设计来读取 FileSystemWatcher 事件。

BlockingCollection 概述

如果您有一些不需要处理的 FileSystemWatcher 事件,请快速关闭它们。
或者,如果有些人的处理速度比其他人快,则有一个单独的集合来减少总计数。

于 2012-12-17T15:26:20.177 回答
3

非分页内存大小有限(更新:现代版本的 Windows 没有以前版本那样严格的限制,内存量现在是一个灵活的值,取决于 Windows 可用的整体 RAM)并且非常重要内核模式居民(设备驱动程序,操作系统本身)。在没有严格控制的情况下消费它会很快导致系统不稳定,更糟糕的是,你不会找到导致这种不稳定的原因。

此外,正如评论所暗示的,重要的不是缓冲区大小,而是从缓冲区中删除数据的速度。

在大多数情况下,文件系统过滤器驱动程序会比 FileSystemWatcher 做得更好。好处是您可以拥有所需的任何日志缓冲区(因为您可以在所需的任何内存中创建它,并且不受非分页内存的限制)并且您可以在事件发生时处理事件,而不是在事件发生后处理。此外,您可以过滤比 FileSystemWatcher 更精细的请求。

于 2012-12-17T15:16:05.507 回答