Fsnotify watcher использует слишком много памяти

(извините за плохой английский)

я работаю над наблюдателем файлов, который будет контролировать все дерево 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{})

Сколько каталогов находится в папке c:\Users? (т.е. сколько вызовов watcher.Add(path)?) Какова реализация watcher?

Paul Hankin 24.08.2024 19:01

объявил int и увеличил его на 1 каждый раз, когда в watcher.Add(path) нет ошибки. там написано 163902

baydırman 24.08.2024 19:18

То есть, если общий объем используемой оперативной памяти составляет 10 ГБ, на каждый просматриваемый файл используется 64 КБ? А какова реализация watcher?

Paul Hankin 24.08.2024 19:24

из-за моего плохого английского я не совсем понял, что вы имели в виду. но я обновил свой вопрос и включил обработку событий наблюдателей.

baydırman 24.08.2024 19:43

Серверная часть Windows fsnotify выглядит так, как будто она использует (по умолчанию) буфер размером 64 КБ для каждого добавленного пути. github.com/fsnotify/fsnotify/blob/v1.7.0/…

Paul Hankin 25.08.2024 13:37
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
2
5
58
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Утечки памяти нет, просто вы используете 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) в случае «большого всплеска событий», что может быть или не быть проблемой для вашего варианта использования.

Другие вопросы по теме