(извините за плохой английский)
я работаю над наблюдателем файлов, который будет контролировать все дерево C:\Users. но он использует слишком много оперативной памяти (около 10 ГБ). Я думаю, что есть утечка памяти.
я использую библиотеки "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{})
объявил int и увеличил его на 1 каждый раз, когда в watcher.Add(path)
нет ошибки. там написано 163902
То есть, если общий объем используемой оперативной памяти составляет 10 ГБ, на каждый просматриваемый файл используется 64 КБ? А какова реализация watcher
?
из-за моего плохого английского я не совсем понял, что вы имели в виду. но я обновил свой вопрос и включил обработку событий наблюдателей.
Серверная часть Windows fsnotify
выглядит так, как будто она использует (по умолчанию) буфер размером 64 КБ для каждого добавленного пути. github.com/fsnotify/fsnotify/blob/v1.7.0/…
Утечки памяти нет, просто вы используете fsnotify
, который в Windows выделяет буфер размером 64 КБ для каждого просматриваемого пути. См.: https://github.com/fsnotify/fsnotify/blob/v1.7.0/backend_windows.go#L274
Вы смотрите 163902 пути (по вашим комментариям), а 163902*64КБ это очень близко к 10ГБ.
Вы можете настроить меньший размер буфера (минимум 4 КБ), используя watcher.AddWith(path, fsnotify.WithBufferSize(4096))
вместо watcher.Add(path)
. В документации предполагается, что это увеличит вероятность переполнения событий (fsnotify.ErrEventOverflow
) в случае «большого всплеска событий», что может быть или не быть проблемой для вашего варианта использования.
Сколько каталогов находится в папке c:\Users? (т.е. сколько вызовов
watcher.Add(path)
?) Какова реализацияwatcher
?