Утечка памяти произошла в проекте Python Google App Engine. Любой эффективный способ написать мою операцию?

У меня есть проект GAE, написанный на Python. Я сделал cron для выполнения пакетной операции. Но он достиг мягкого ограничения частной памяти экземпляра F1, которое после нескольких итераций составляет 124 МБ. Может ли кто-нибудь помочь мне написать этот код более эффективно, надеюсь, в пределах 124 МБ. len(люди) должно быть меньше 500.

def cron():
    q = Account.all().filter('role =', 1)
    people = [e for e in q]
    for p in people:
        s = Schedule.available(p)
        m = ScheduleMapper(s).as_dict()
        memcache.set('key_for_%s' % p.key(), m)

Это сервер разработки, и я не хочу обновлять свой класс экземпляра. Кроме того, я хочу избежать использования сторонних библиотек, таких как numpy и pandas.

Я добавил сборку мусора в последнюю строку цикла for. Но, похоже, это не работает.

del s
m.clear()
import gc
gc.collect()

comment
Вы не упомянули, сколько объектов вы извлекаете. Также я бы переместил цикл в функцию, а gc наружу. Когда вы говорите об итерациях, вы имеете в виду вызовы обработчика cron или внешнего или внутреннего цикла?   -  person Tim Hoffman    schedule 02.10.2017
comment
Спасибо за комментарий! Количество сущностей должно быть меньше 500. Что касается итераций, я имел в виду внутренний цикл.   -  person steve    schedule 02.10.2017
comment
сколько на внутренней петле. Не видя ваших моделей, я подозреваю, что вы где-то держите какие-то ссылки.   -  person Tim Hoffman    schedule 02.10.2017
comment
Я не считал, сколько именно, но закончил на несколько. Да, я тоже подозревал отсылку. Но как освободить все воспоминания?   -  person steve    schedule 02.10.2017
comment
Из того, что я видел, del list или dict.clear() не освобождают все воспоминания.   -  person steve    schedule 02.10.2017
comment
Я думаю, нам нужно просмотреть некоторые детали в available() и посмотреть на то, что вы делаете без всех промежуточных объектов. Посмотрите на использование карты для применения функций к сущностям, а не на разрешение всего списка, а затем повторение по нему. Такие вещи. У меня есть процессы с запросами, которые работают с тысячами сущностей, а мои экземпляры F1 работают в течение нескольких дней и никогда не выходят из строя из-за ошибок нехватки памяти.   -  person Tim Hoffman    schedule 03.10.2017


Ответы (1)


Чтобы увидеть, возможно ли вообще поместить его в объем памяти, который вы хотите изменить, чтобы получить один объект, и проверьте, можете ли вы успешно выполнить цикл for для этого объекта. Или просто добавьте break в конце цикла for :)

Если это не сработает, вам необходимо обновить класс экземпляра.

Если эксперимент работает, вы можете разделить работу, используя курсоры запроса. в несколько задач push-очереди, каждая обработка только одного объекта или только нескольких из них.

Возможно, взгляните на Google appengine: производительность очереди задач для обсуждения. о разделении работы на несколько задач (хотя причиной разделения в этом случае было превышение срока запроса, а не лимита памяти).

Обратите внимание, что даже при использовании нескольких задач все еще можно достичь предела памяти (см. 35192334">App Engine Deferred: отслеживание утечек памяти), но, по крайней мере, работа будет выполнена, даже если конкретный экземпляр будет перезапущен (по умолчанию задачи повторяются).

person Dan Cornilescu    schedule 09.10.2017