(抱歉英语不好)
我正在开发一个文件观察器,它将监视整个 C:\Users 树。但它使用了太多的 RAM(大约 10 GB)。我认为存在内存泄漏。
我正在使用
"github.com/fsnotify/fsnotify"
和 path/filepath
库。
观察者只观察创建和删除事件,我运行
filepath.WalkDir()
而没有观察者添加目录,这不是问题。
go func() {//handling events
for {
select {
case event, ok := <-watcher.Events:
if !ok {
return
}
if event.Has(fsnotify.Create) {
log.Println("file created: ", event.Name)
} else if event.Has(fsnotify.Remove) {
log.Println("file removed: ", event.Name)
}
case err, ok := <-watcher.Errors:
if !ok {
return
}
log.Println("error:", err)
}
}
}()
var info fs.FileInfo
var err1 error
err = filepath.WalkDir("C:\\Users", func(path string, di fs.DirEntry, err error) error {
info, err1 = os.Stat(path)
if err1 != nil {
log.Print("os.Stat error:")
log.Println(err)
}
if info.IsDir() {
err1 = watcher.Add(path)
if err1 != nil {
log.Println("watcher.add error: ", path)
log.Println(err1)
}
}
return nil
})
if err != nil {
log.Fatalf("error with walkdir: %v", err)
}
log.Println("DONE")
<-make(chan struct{})
没有内存泄漏,只是您使用的是
fsnotify
,它在 Windows 上为每个监视路径分配 64KB 缓冲区。请参阅:https://github.com/fsnotify/fsnotify/blob/v1.7.0/backend_windows.go#L274
您正在观看 163902 个路径(根据您的评论),并且 163902 * 64KB 非常接近 10GB。
您可以使用
watcher.AddWith(path, fsnotify.WithBufferSize(4096))
而不是 watcher.Add(path)
配置较小的缓冲区大小(最小为 4KB)。文档表明,如果存在“大量事件”,这将增加事件溢出的可能性 (fsnotify.ErrEventOverflow
),这对于您的用例来说可能是也可能不是问题。