Как я могу сделать так, чтобы мой сервер (написанный на Golang) не заканчивался в памяти?

У меня есть небольшой сервер, который должен обрабатывать много файлов. Файлы отправляются по запросу PUT на сервер. Я использую пакет net / http для сервера. Я знаю,что для каждого запроса открывается процедура go. Но проблема в том, что после завершения запроса используемая память обработчика не освобождается.

Сервер (должен) работать на Raspery Pi 3 с 1 ГБ памяти. Проблема в том, что у него заканчивается память, когда я отправляю много файлов. В этот момент я не могу ждать, пока сборщик мусора освободит память.

Эти две темы посвящены проблеме:

Почему блок памяти не очищается сборщиком мусора?

Go 1.3 сборщик мусора не освобождает память сервера обратно в систему

Но для моей проблемы нет решения.

Теперь вопрос: есть ли способ сделать обработчик http помеченным как полностью готовый, чтобы сборщик мусора освобождал память для вызывающей подпрограммы? Я пытался добавить a returnв конце обработчика, но это не работает. Я все еще бегу без памяти.

1 ответ

  1. Короткий ответ:
    Я обновлен до версии 1.6.2. Теперь нет дополнительного выделения памяти для каждой подпрограммы.


    Спасибо всем за ваши комментарии. Они вернули меня на правильный путь.

    Потребление памяти происходит от функции, которая создает хэш md5 для каждого загруженного файла. Таким образом, 100MB файл должен также 100Mb памяти. Go в версии 1.3 выделяет для каждого запроса (go routine) новую память. Так после max. 1 ГБ загруженных файлов у Raspbery закончилась память.

    Откуда берутся все горотины?

    Один комментарий был о логике, чтобы открыть процедуру go для каждого запроса. Эта логика не была реализована мной, это внутри того, как go обрабатывает запросы.

    Подробнее о том, что вы можете найти в этой большой книге с открытым исходным кодом о создании веб-приложений с Go: Get into http package

    Что происходит сейчас в версии 1.6.2?

    Для каждой загрузки сервер выделяет память. Разница теперь в том, что Go резервирует объем памяти, но использует его также для других процедур.

    Пример для версии 1.6.2:

    1st file 10 MB -> 10 MB RAM is used by the server
    2nd file 5 MB -> 10 MB RAM is used by the server
    3rd file 100 MB -> 100 MB RAM is used by the server
    4th file 50 MB -> 100 MB is used by the server
    

    Таким образом, пока файл не будет больше памяти, сервер должен работать.