Google App Engine数据库查询内存使用量

时间:2015-08-06 10:43:45

标签: python google-app-engine google-cloud-datastore google-app-engine-python

当我对一大组小对象(只有少量短字符串和布尔属性的15k对象)运行查询时,没有对这些对象做任何事情,我看到我的实例的内存使用量不断增加(增加70Mb)。内存增加看起来并不像它只需要查询就需要保留在内存中的数据量。

我使用的循环如下:

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 :我做了一些黑客攻击,让guppy在dev_appserver上工作,这似乎指出,在循环结束时显式gc.collect()后,大多数记忆是由'google.appengine.datastore.entity_pb.Property'的字典所消耗的。

2 个答案:

答案 0 :(得分:2)

每个模型实体都有一些头脑。

您查询将对象作为初学者的Protobuf返回。

因此,您将为结果集添加一系列批处理的原型。

然后解码。每个解码的实体包括属性名称以及每个实体的数据。你有15K实体。例如,你的财产名称有多大。

因此,您在内存中至少有两个结果集副本(可能更多),不包括您对模型类实例所做的任何其他操作。

您的代码/循环没有机会进行垃圾收集,而且可以/稍后发生。

查看apptrace等工具来帮助进行内存分析。

答案 1 :(得分:1)

我已经向应用引擎团队报告了这一点,他们似乎确认这实际上是一个问题(怀疑是处理游标)。