Фон
Я создал API и выполнил профилирование использования памяти и времени обработки для каждого веб-сервиса, используя это руководство и gem profiler memory .
Я создал таблицу для сохранения всех результатов профилирования следующим образом:
Request | Memory Usage(b) | Retained Memory(b) | Runtime(seconds)
----------------------------------------------------------------------------
Post Login | 444318 | 35649 | 1.254
Post Register | 232071 | 32673 | 0.611
Get 10 Users | 11947286 | 2670333 | 3.456
Get User By ID | 834953 | 131300 | 0.834
Примечание: все номера являются средним числом вызовов одной и той же услуги 3 раза подряд.
И я прочитал много руководств и ответов (например, это и это ) говорит, что сборщик мусора отвечает за освобождение памяти, и мы не должны явно вмешиваться в управление памятью.
Затем я просто заставил сборщик мусора запускаться после каждого действия (в целях тестирования), добавив следующий фильтр в APIController:
after_action :dispose
def dispose
GC.start
end
И я обнаружил, что использование памяти сокращается слишком сильно (более чем на 70%), оставшаяся память почти такая же, как и раньше, и время выполнения также уменьшается.
Request | Memory Usage(b) | Retained Memory(b) | Runtime(seconds)
----------------------------------------------------------------------------
Post Login | 38636 | 34628 | 1.023
Post Register | 37746 | 31522 | 0.583
Get 10 Users | 2673040 | 2669032 | 2.254
Get User By ID | 132281 | 128913 | 0.782
Вопросы:
- Полезно ли добавлять такой фильтр и каковы побочные эффекты?
- Я думал, что время выполнения будет больше, чем раньше, но, кажется, меньше, в чем может быть причина?
Обновление:
Я использую Ruby 2.3.0 и gc_tracer gem для мониторинга состояния кучи, потому что боюсь, что старые проблемы с сборкой мусора выделены в Ruby 2.0 и 2.1
Проблема в том, что Ruby GC запускается на общем количестве объектов,
а не общий объем используемой памяти
Затем, чтобы провести стресс-тест, я запускаю следующее:
while true
"a" * (1024 ** 2)
end
и в результате этого использование памяти не превышает следующих пределов ( было превышено ранее и GC не будет запускаться ):
RUBY_GC_MALLOC_LIMIT_MAX
RUBY_GC_OLDMALLOC_LIMIT_MAX
Так что теперь я почти уверен, что те же самые GC
проблемы 2.0 и 2.1 больше не существуют в 2.3, но все же получают следующие положительные результаты, добавив вышеупомянутый фильтр (after_action :dispose
):
- Объем памяти кучи увеличен на 5% до 10% ( проверьте этот связанный вопрос )
- Общее время выполнения увеличено на 20% до 40% (тест выполнен с использованием стороннего инструмента Почтальон , который использует мой API)
Я все еще ищу ответы на два моих вопроса выше.
Любая обратная связь будет принята с благодарностью