2016-08-05 2 views
0

Я видел этот Python вопрос: App Engine Deferred: Tracking Down Memory LeaksОтслеживание утечки памяти в приложении Google App Engine Golang?

... Кроме того, я столкнулся с этой ужасной ошибкой:

Exceeded soft private memory limit of 128 MB with 128 MB after servicing 384 requests total

...

After handling this request, the process that handled this request was found to be using too much memory and was terminated. This is likely to cause a new process to be used for the next request to your application. If you see this message frequently, you may have a memory leak in your application.

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

После проверки приложения я не вижу ничего очевидного в отношении того, где может возникнуть утечка (например, незакрытые буферы и т. Д.) ... и все, что бы это ни было, должно быть очень маленьким, но, возможно, Общая ошибка.

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

+1

[Профиль кучи] (https://blog.golang.org/profiling-go-programs) (описанный в этой ссылке вместе с распределением и профилями процессора) может рассказать вам, что использует большую часть ОЗУ. ['runtime/pprof'] (https://golang.org/pkg/runtime/pprof/) может отправлять кучу prof. любому 'Writer', включая' http.ResponseWriter'; вы могли бы запустить это за некоторыми auth в производстве. – twotwotwo

+0

Вы можете посмотреть на это по-другому: временно обновить до следующего (1 или 2) класса экземпляров и проверить тренд использования памяти. Если он стабилизируется через некоторое время, класс экземпляра был действительно слишком маленьким - сделанный :) Если он продолжает расти (в конечном итоге вызывает перезагрузку экземпляра), то действительно происходит утечка памяти, и расследование * может потребоваться * (частота перезапуска экземпляра * может * быть терпимым с классом более высокого экземпляра). Можно было бы посмотреть на такие перезагрузки, как периодическая функция обновления/самоочистки периодического экземпляра, позволяющая, например, сосредоточиться на других, более насущных вопросах;) –

+0

@twotwotwo У меня есть эта регистрация сейчас, спасибо за идею. –

ответ

1

Для начальной точки вы можете попробовать pprof.WriteHeapProfile. Он напишет любой номер Writer, включая http.ResponseWriter, чтобы вы могли написать представление, которое проверяет наличие некоторого auth и дает вам профиль кучи. Досадно, что это действительно отслеживает ассигнования, а не то, что остается выделено после GC. Таким образом, в некотором смысле это говорит вам, что голодает RAM, но не нацелено конкретно на утечки.

Стандартный expvar пакет может разоблачить некоторые JSON, включая memstats, который говорит вам о ШС и числа ALLOCS и высвобождает конкретных размеров распределения (example). Если есть утечка, вы можете использовать allocs - frees, чтобы получить представление о том, растут ли они большие ассигнования или небольшие, но это не очень мелкозернистые.

Наконец, есть a function to dump the current state of the heap, но я не уверен, что он работает в GAE, и, похоже, он редко используется.

Обратите внимание, что для того, чтобы поддерживать работу GC, процессы Go увеличиваются примерно вдвое больше, чем их фактические данные в реальном времени как часть нормального стационарного режима работы. (Точный% он растет до того, как GC зависит от runtime.GOGC, который люди иногда увеличивают, чтобы сохранить работу коллектора в обмен на использование большего объема памяти.) (Очень старая) нить предлагает App Engine processes regulate GC like any other, хотя они могли бы изменить ее с 2011 года. Во всяком случае, если вы 'медленно выделяя (хорошо для вас!) вы должны ожидать медленный рост процесса; это просто, что после каждого цикла сбора данных использование должно упасть обратно вниз.

1

Возможный способ проверить, действительно ли у вашего приложения утечка памяти - временно обновить класс экземпляра и проверить шаблон использования памяти (в консоли разработчика на странице Instances выберите вид Memory Usage для соответствующей версии модуля).

Если шаблон в конечном итоге выравнивается, и экземпляр больше не перезапускается, то действительно, ваш класс экземпляра был слишком низким. Done :)

Если шаблон использования продолжает расти (со скоростью, пропорциональной активности приложения), то в действительности у вас есть утечка памяти. Во время этого упражнения вы можете также уменьшить область поиска - если вам удастся сопоставить области роста графика с определенными действиями приложения.

Даже если есть утечка, использование более высокого класса экземпляра должно увеличить время между перезапусками экземпляра, возможно, даже сделать их допустимыми (что сопоставимо с автоматическим отключением динамически управляемых экземпляров, например). Это позволило бы провести исследование утечки памяти на заднем плане и сосредоточиться на более насущных вопросах, если это вас интересует. Можно было бы посмотреть на такие перезагрузки, как функция обновления/самоочистки экземпляра :)

Смежные вопросы