[英]Google App Engine DB Query Memory Usage
当我对一大堆小对象(只有几个短字符串和布尔属性的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()
调用gc.collect()
时; 它返回0
,并没有帮助。
更新2 :我做了一些黑客工作,以使gc.collect()
在dev_appserver上工作,这似乎表明,在循环末尾显式gc.collect()
之后,大部分内存被Google的“ dict”占用了。 appengine.datastore.entity_pb.Property”。
每个模型实体都有一些开销。
您查询返回对象作为Protobufs作为启动器。
因此,您将为结果集添加一系列批处理的protobuf。
然后将其解码。 每个解码的实体都包括属性名称以及每个实体的数据。 您有15,000个实体。 例如,您的财产名称有多大。
因此,您在内存中至少有两种形式(可能更多)的结果集副本,其中不包括您对模型类的实例所做的任何其他操作。
您的代码/循环没有机会进行垃圾回收,并且以后可能会发生。
看一下apptrace之类的工具来帮助进行内存分析。
我已将此问题报告给App Engine团队,他们似乎确认这实际上是一个问题(怀疑是与游标的处理有关)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.