Использование памяти запросов к БД Google App Engine

Когда я выполняю запрос к большому набору небольших объектов (15 тыс. Объектов с несколькими короткими строковыми и логическими свойствами), ничего не делая с этими объектами, я вижу, как непрерывно увеличивается использование памяти моего экземпляра (увеличение на 70 МБ). Увеличение памяти не выглядит пропорционально количеству данных, которые ему когда-либо нужно хранить в памяти только для запроса.

Цикл, который я использую, следующий:

cursor = None
while True:
  query = MyModel.all()
  if cursor:
    query.with_cursor(cursor)
  fetched = 0
  for result in query.run(batch_size = 500):
    fetched += 1

    # Do something with 'result' here. Actually leaving it empty for 
    # testing to be sure I don't retain anything myself

    if fetched == 500:
      cursor = query.cursor()
      break
  else:
    break

Чтобы быть уверенным, что это не из-за appstats, я звоню appstats.recording.dont_record() не записывать какую-либо статистику.

Кто-нибудь знает, что может происходить? Или какие-либо указатели о том, как отладить / профиль этого?

Обновление 1: я включил gc.set_debug(gc.DEBUG_STATS) в производственном коде, и я вижу, что сборщик мусора вызывается регулярно, поэтому он пытается собрать мусор. Когда я звоню gc.collect() в конце цикла (также в конце запроса); это возвращается 0и не помогает.

Обновление 2: я сделал несколько хакеров, чтобы заставить гуппи работать на dev_appserver, и это, казалось, указывало, что после явного gc.collect() в конце цикла большая часть памяти была занята "диктом google.appengine.datastore.entity_pb.Property".

2 ответа

Решение

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

Каждый модельный объект имеет некоторые накладные расходы.

Ваш запрос возвращает объекты как Protobufs для начинающих.

Таким образом, вы получите серию пакетных протобуфов для набора результатов.

Тогда это расшифровано. Каждый декодированный объект включает в себя имена свойств, а также данные для каждого объекта. У вас есть 15 тысяч объектов. Насколько велики ваши имена свойств, например.

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

Ваш код / ​​цикл не имеет возможности для сборки мусора, и это может / произойдет позже.

Посмотрите на инструменты, такие как apptrace, чтобы помочь профилированию памяти.

Другие вопросы по тегам