Проблема с памятью в ASP.NET Core

280
13 августа 2021, 22:20

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

При запуске проекта локально память имеет такое состояние -

И оно никак не растет.

 if (data.Length > 2 )
        {
            dataFromJSON.Append(await System.IO.File.ReadAllTextAsync("cities.json")); 
            CitiesModel model = JsonConvert.DeserializeObject<CitiesModel>(dataFromJSON.ToString());
            Regex regex = new Regex($"^{data.ToLower()}");
            var s = model.Cities.Where(x => regex.IsMatch(x.CityName.ToLower())).ToList();
            return Ok(JsonConvert.SerializeObject(s));
        }

Но когда я делаю запрос через поле, то память начинает сильно расти при работе - c этим кодом. ReadAllTextAsync вытягивает больше 80к названий и потом я еще делаю DeserializeObject и память вырастает до 300+-

Но меня пугает не это, а то, что растет с каждым запросом и никак не уменьшается. Сделал 5 запросов и вот такое щас

Как решить эту проблему, думаю, что это не нормально и не должно так быть или объясните, кто понимает, почему память не опускается?

UPDATE

Оптимизировал так и работает лучше, все равно память растет, если как говорят, что GC сам очистить когда нужно будет.

Если есть критика в коде - пишите, как можно еще оптимизировать, чтобы не засорять память.

    [HttpPost]
    public async Task<IActionResult> GetCity()
    {
        string data = null;
        using (StreamReader reader = new StreamReader(Request.Body))
        {
            data = await reader.ReadToEndAsync();
        }
        CitiesModel model=null;
            JsonSerializer serializer = new JsonSerializer();
            using (FileStream ss = System.IO.File.Open("cities.json", FileMode.Open))
            using (StreamReader sr = new StreamReader(ss))
            using (JsonReader reader = new JsonTextReader(sr))
            {
              model = serializer.Deserialize<CitiesModel>(reader);
            }
           Regex regex = new Regex($"^{data.ToLower()}");

        var s = new List<CityModel>();
        foreach (var city in model.Cities)
        {
            if (regex.IsMatch(city.CityName.ToLower()))
                s.Add(city);
        }
        System.GC.Collect();
        return Ok(JsonConvert.SerializeObject(s));
    }
Answer 1

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

Это нормально.

Общее решение:

  • Если под нагрузкой приложение не продолжает есть больше-больше-больше и не начинает падать с OutOfMemory - утечки у вас нет. Некий устоявшийся объем памяти, выделенные приложению под нагрузкой - это нормально.
  • Не вызывайте вручную System.GC.Collect. От "засорения памяти" это не поможет, единственное, чего вы добъетесь - тормоза под нагрузкой. Сборщик памяти и так отработает, просто не сразу (не во время запроса, когда надо результат отдать как можно быстрее!), а чуть позже.
  • Если приложение все-таки течет (по настоящему, выедает все больше памяти, и начинает падать с OOM, а не просто съедает пару сотен мегабайт, и стабилизируется на них, как у вас) - возьмите профайлер памяти (утилиту, которая у вас на скриншотах), сделайте в ней несколько снимков, и найдите место, где течет.
Answer 2

В вашем коде смущает вызов функции dataFromJSON.Append.

  1. Не ясно dataFromJSON это локальная переменная или член класса. Если второй вариант, то у вас утечка.
  2. Вообще тут читать весь файл в память как строку смысл в мало, я верю что у функции конвертации в объект есть метод принимающий поток из файла напрямую или через reader.

Уверен, если в этом вызове сделать правки потребление памяти должно уменьшиться и утечки не будет. Можно перепроверить момент с утечкой и для теста вызвать System.GC.Collect() по нажатию на тестовуюи кнопку или в профайлере памяти.

READ ALSO
Удаление \n из строки

Удаление \n из строки

Это произошло внезапно

333
Архивация файлов, находящихся в MemoryStream

Архивация файлов, находящихся в MemoryStream

На сервере в БД хранятся файлыНеобходимо отправлять эти файлы на почту

244
реализация tf-idf c#

реализация tf-idf c#

Нужна помощь, пожалуйстаНужно вычислить idf для конкретного текста в richtexbox (tf есть)

237
Сериализация enum в json в виде строки

Сериализация enum в json в виде строки

У меня есть класс со свойством типа enum property и при сериализации в json оно выводится как число, в то время как мне надо чтобы результат был в виде...

189