当我尝试对Google App Engine blobstore进行简单写入时,我目前超出了内存限制。编写此代码以使其不泄漏内存的正确方法是什么?
from __future__ import with_statement
from google.appengine.api import files
from google.appengine.api import blobstore
def files_test(limit):
file_name = files.blobstore.create(mime_type='application/octet-stream')
try:
with files.open(file_name, 'a') as f:
for x in range(limit):
f.write("Testing \n")
finally:
files.finalize(file_name)
return files.blobstore.get_blob_key(file_name)
files_test(4000)产生错误:
在为27个请求提供服务后,超出了157.578 MB的软私有内存限制
答案 0 :(得分:3)
不幸的是,python的垃圾收集器并不完美。你做的每一次写操作都会创建许多小对象(通过协议缓冲区创建),由于某种原因,这些小对象不是由python动态收集的。我发现在mapreduce库中我必须要做
import gc
gc.collect()
不时让垃圾收集者高兴。
答案 1 :(得分:0)
由于它是Python 2.5,xrange
应该优于range
,不是吗?
答案 2 :(得分:0)
您应该立即写入所有数据以避免问题并加快速度 - 优化它 - 它应该停止问题但不能解决错误 - > http://docs.python.org/library/stringio.html。考虑到file.write可能不是简单的写入,但是对RPC API的请求设置很慢 - 请参阅SDK代码 - 避免多次调用/缓冲。
如此少量的数据4000 * 9不应该出现 - 它看起来像Google API中的错误 - 只需报告http://code.google.com/p/googleappengine/issues/list?can=2&q=&sort=-id&colspec=ID%20Type%20Component%20Status%20Stars%20Summary%20Language%20Priority%20Owner%20Log
考虑将'create'标记为实验http://code.google.com/intl/pl/appengine/docs/python/blobstore/overview.html#Writing_Files_to_the_Blobstore
修复也最终确定错误 - 如果异常,则无法完成无效文件或返回结果!
import StringIO
from __future__ import with_statement
from google.appengine.api import files
from google.appengine.api import blobstore
def files_test(limit):
output = StringIO.StringIO()
# workaround!
for x in range(limit):
output.write("Testing \n")
file_name = files.blobstore.create(mime_type='application/octet-stream')
try:
with files.open(file_name, 'a') as f:
# workaround!
f.write(output.getvalue())
finally:
output.close()
files.finalize(file_name)
return files.blobstore.get_blob_key(file_name)
答案 3 :(得分:0)
也许我错了,但我很确定write()的调用次数可能就是问题所在。 我认为这是问题,因为当我尝试保存用户上传的文件时,我遇到了类似的问题。
对我而言,这导致了问题:
with files.open(file_name, 'a') as f:
for chunk in read_in_chunks(data):
f.write(chunk)
对我来说,当我将块大小更改为1Mb而不是1Kb时,问题就消失了。