Профилирование использования памяти в игре! Фреймворк

#playframework #akka

#playframework #akka

Вопрос:

У меня есть игра! Рамочное приложение, которое я запускаю в производство уже 3 года. Однако недавно мне пришлось обновить версию до 2.8 (с 2.5) и необходимо изменить некоторые устаревшие функции. В процессе я начал использовать больше актеров Akka.

Однако теперь у меня заканчивается память в течение определенного периода времени (2-5 дней), чего раньше не было. Поскольку обновление было большой переписью, я не могу легко вернуться назад, поэтому мне интересно, легко ли понять, почему использование моей памяти постоянно увеличивается.Когда объем памяти почти на максимуме, Akka webstreath перестает отвечать (но ошибки PermGen пока нет).

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

введите описание изображения здесь

Сначала я думал, что это проблема с новыми актерами Akka, созданными и не выпущенными. Хотя количество участников увеличивалось, после того, как некоторые из них были одноэлементными (в них нет переменных), это, похоже, не так.

Есть ли способ узнать, что занимает эту память? Я ожидаю, что это то, на что есть ссылка, и поэтому память не освобождается, но ее трудно найти, если нет подсказки.

[РЕДАКТИРОВАТЬ] После запуска MAT кажется, что akka.актер.ActorCell сохраняется со всеми данными JSON, которые я отправляю клиенту. Это процедура. Есть ли причина, по которой данные не публикуются? Нужно ли мне что-то с материализатором или исходным кодом?

  private void sendDeviceData(List<Device> devices){
    ObjectNode response = Json.newObject();
    ObjectNode statusScreen = response.putObject("statusScreen");
    ArrayNode items = statusScreen.putArray("devices");         
    for(Device device : devices) {
        items.add(Json.parse(device.getStatusJson()));
    }
    Source<JsonNode, NotUsed> source = Source.single(response);
    source.to(hubSink).run(mat);
}
  

[ПРАВИТЬ 2]
Пожалуйста, найдите прикрепленный скриншот дампа. По какой-то причине кажется, что все это вложено.

введите описание изображения здесь

Комментарии:

1. Попробуйте собрать дамп кучи с помощью jmap (см. baeldung.com/java-heap-dump-capture ), а затем проанализируйте его в Eclipse MAT ( eclipse.org/mat ) или любой другой профилировщик памяти.

2. Отлично, что вернул этот «akka. актер. ActorCell» занимает 92% памяти. Кажется, что все данные, отправляемые через WS в webintrface, вложены друг в друга. Я обновил свой код.

3. Как вы создаете своих актеров? Один участник на запрос? Обратите внимание, что актеры останавливаются только в том случае, если они явно остановлены: просто потому, что на актера не указывают живые ActorRef s, это не приводит к остановке актера и восстановлению состояния, удерживаемого ActorCell . Итак, если вы создаете актера по запросу, вы должны остановить актера после запроса.

4. Записи AbstractNodeQueue, скорее всего, являются почтовым ящиком субъекта, поэтому неудивительно, что отображается ActorCell, который является фактической реализацией субъекта, которому принадлежит этот почтовый ящик. Звучит так, как будто есть актер, который не обрабатывает свой почтовый ящик (достаточно быстро). Я бы посмотрел на гистограмму в MAT и посмотрел, какие типы сообщений это могут быть.

5. Я думаю, что, возможно, нашел проблему. Чтобы отправить сообщение обратно клиенту, я использовал ‘source.to (hubSink).run(mat);’. Когда я изменил это на ‘hubSink.RunWith (source, mat);’, очевидное увеличение объема памяти прекратилось. Теперь мне нужно будет выполнить длительный запуск с дампом памяти, чтобы увидеть, действительно ли это произошло.