难道真的那么昂贵,增加FileSystemWatcher.InternalBufferSize?难道真、昂贵、InternalBufferSize、FileSystemWatcher

2023-09-03 04:51:01 作者:假装不帅

我使用了一个 FileSystemWatcher的来监测变化的文件夹中,但只要我有超过几百修改,在很短的时间,我想一些他们因为内部缓冲区溢出。所以,我想增加 InternalBufferSize (我知道这不会真正解决问题,但它将使不太可能发生),但我看到这个警告在documentation:

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.

我的问题是:是否真的重要?大多数计算机今天的内存至少1GB,所以在我看来,如果我设置缓冲区大小为1MB(而不是默认的8KB),它不应该真正关注的是1MB不能被交换到磁盘。还是我失去了一些东西?我不知道很多关于低层次的东西,如分页/无分页内存,所以我不知道什么样的影响将是...

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...

推荐答案

在缓冲器被分配的内存肯定是precious资源。 Windows将无法处理耗尽内存池井,司机将开始随机失败。池的大小是动态设置(但可改变),并取决于可用的RAM量。

The memory in which the buffer gets allocated is certainly a precious resource. Windows will not deal with exhausting the memory pool well, drivers will start to fail at random. The size of the pool is dynamically set (but can be changed) and depends on the amount of available RAM.

FSW要求的默认缓冲区大小为8192字节。没有太多的现代机器。底层WINAPI功能不会让你索要超过64KB。一个条目是缓冲区是12字节加上文件路径倍2的长度。因此,最坏的情况是8192 /(12 + 260 * 2)= 15通知的缓冲耗尽。这应该工作在大多数情况下,没有太多的麻烦,除非你监控整个驱动器,或者在你正在看的目录非常高的磁盘流量。在这种情况下,要求更大的缓冲区是公平的。没有黄金规则时,一定让你的实施FileSystemWatcher.Error事件知道的你已经有了一个缓冲的问题。

The default buffer size that FSW asks for is 8192 bytes. Not much on modern machines. The underlying winapi function will not allow you to ask for more than 64KB. An entry is the buffer is 12 bytes plus the length of the file path times two. So worse case is 8192 / (12 + 260*2) = 15 notifications before the buffer runs out. That should work in most circumstances without much trouble, unless you monitor an entire drive or have very high disk traffic in the directory you are watching. In which case asking for a bigger buffer is fair. There is no golden formula, be sure to implement the FileSystemWatcher.Error event so you know that you've got a buffer problem.

在大多数实际情况下,你需要处理小心FSW事件。它们将提高,而一个过程仍然具有上的文件的锁定。所以,做事情像打开或复制文件的麻烦。你处​​理,通过把通知在一个线程安全的队列,并使用另一个线程来试穿文件,如有必要可重复获得锁。这样的队列现在是自动也是一个很好的方式,快速清空缓冲区。你得看现在的唯一的事情是,队列不炸掉超过合理的比例,这将使你的程序崩溃与OOM。

In most practical cases you need to deal with the FSW events carefully. They will be raised while a process still has a lock on a file. So doing things like opening or copying the file are troublesome. You deal with that by putting the notifications on a thread-safe queue and use another thread to try to acquire a lock on the file, repeatedly if necessary. Such a queue is now automatically also a very good way to quickly empty the buffer. The only thing you've got to watch for now is that the queue doesn't blow up beyond reasonable proportions that will make your program crash with OOM.