【问题标题】:FileSystemWatcher takes memory after disposing?FileSystemWatcher 处理后占用内存?
【发布时间】:2017-04-21 12:27:41
【问题描述】:

我有一个使用 FileSystemWatcher 类的程序。它通过在文件夹中的每个子文件夹上添加新的 FileSystemWatcher 来工作,每个 FileSystemWatcher 占用 8 kB 的内存。

FileSystemWatchers 被添加到“观察者”列表中,其中可能有数千个。

当我调用方法时

 watchers.ForEach(x => x.Dispose()); 

我希望它们都停止(他们确实这样做了),但是没有从 RAM 中释放内存

请问我该如何解决这个问题?

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        protected virtual void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {                        
                    watchers.ForEach(x => x.Dispose());
                    watchers.Clear();
                }
                disposed = true;
            }                
        }

【问题讨论】:

  • IncludeSubdirectories 不会帮助监视子文件夹而不是创建许多监视者吗?
  • Dispose 释放非托管资源,但不释放托管内存。
  • IncludeSubdirectories 是我的第一次尝试,但是当有很多“移动”时,缓冲区不够大,我读到了更好的地方以创建更多更小的观察者。
  • 您订阅了FileWatcher events 中的任何一个吗?如果是这样,那么订阅该事件的对象将引用 FileWatcher 对象,直到订阅者取消订阅该事件,或者订阅者本身被垃圾回收 - 所以订阅者将保持活动 FileWatcher即使您认为您已经处置了它并删除了对它的所有其他引用。
  • 不,Dispose() 不会取消订阅 - 您必须手动取消订阅。这适用于所有类型,而不仅仅是FileSystemWatcher。请记住,每当您使用source.SomeEvent += someHandler() 订阅时,右侧将左侧保留在内存中,直到订阅者被垃圾回收,或者您调用source.SomeEvent -= someHandler()

标签: c# filesystemwatcher


【解决方案1】:

当您将所有观察者放入列表时 - 您已经从列表中创建了对它们的引用,因此垃圾收集器无法在此列表“活动”时释放观察者占用的内存。

您还必须将它们从列表中删除:

watchers.Clear();

此外,如果您有其他对观察者的引用(包括订阅其事件的事件处理程序) - 您必须清除这些引用(也取消订阅事件),以便垃圾收集器释放观察者占用的内存。

在任何情况下,您都不应该期望立即释放内存。垃圾收集器并非一直在运行,因此可能需要一段时间才能释放内存。

您可以使用GC.Collect() 强制垃圾收集器释放内存,但通常不建议这样做。

【讨论】:

  • 它不工作。我做错了什么?我会更新主帖。
  • 我明白为什么不推荐 GC.Collect() - 程序崩溃了。 ;-)
  • @JosefKvita 通常它不应该崩溃。无论如何,调用Collect 是不好的做法,垃圾收集器通常会自动完成它的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-30
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
相关资源
最近更新 更多