@babderos

Почему Go-вебсервер есть так много памяти и не освобождает ее?

Написал веб-сервер на Го
Принимает GET параметр и собирает большой массив

package main

import (
	"net/http"
	"fmt"
	_ "net/http/pprof"
	"strings"
)
func one(w http.ResponseWriter, r *http.Request){
	s := r.URL.Query().Get("s")

	array := []string{}
	for i:=0; i<10000; i++{
		new_s := strings.Repeat(s,1000) // Если вынести за пределы цикла  - потребляет меньше памяти (35мб) но все равно ее не освобождает
		array = append(array, new_s)
	}
	w.Write([]byte("ok"))

}
func main(){
	http.HandleFunc("/one", one)
	fmt.Println("ready")
	server := &http.Server{Addr: ":8008"}
	server.ListenAndServe();
}

При старте занимает 6 мб Озу.

При запуске:

ab -n 1000 -c 100 "http://localhost:8008/" - потребление памяти вырастает до 10мб
ab -n 1000 -c 1 "http://localhost:8008/one?s=1" ~ 30мб
ab -n 1000 -c 100 "http://localhost:8008/one?s=1" ~ 800мб

И во всех случаях она никак не освобождается. Процесс так и продолжает занимать много памяти

Кто подскажет, что тут не так? А то я не понимаю, почему го так много занимает памяти и не освобождает ее даже когда запрос клиента обработан?
  • Вопрос задан
  • 723 просмотра
Решения вопроса 1
После сборки мусора память не возвращается в ОС сразу, потому что если нагрузка снова резко пойдёт, будет быстрее переиспользовать уже аллоцированную приложением память, чем просить её у ОС снова.
Если нагрузка будет долго отсутствовать, гошка должна в конце концов отдать память в ОС.
Это можно сделать вручную через debug.FreeOSMemory()
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@evgensoft
Как уже выше написано - действительно память отдается не сразу, а по возможности переиспользуется.
Т.е. при интенсивной работе расти уже не будет, а если долго не понадобится - будет освобождаться.
Можно вручную вызвать сборку мусора - runtime.GC()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы