Google App Engine / Datastore / Flask / Python 应用程序中的内存泄漏

Kaa*_*Roy 5 python google-app-engine flask google-cloud-datastore

我构建了一个简单的新闻聚合器站点,其中我所有 App Engine 实例的内存使用量不断增长,直到达到限制并因此被关闭。

我已经开始消除我的应用程序中的所有内容,以获得一个最小的可重现版本。这就是我现在所拥有的:


app = Flask(__name__)

datastore_client = datastore.Client()

@app.route('/')
def root():
    
    query = datastore_client.query(kind='source')
    query.order = ['list_sequence']
    sources = query.fetch() 
    
    for source in sources:
        pass
    
Run Code Online (Sandbox Code Playgroud)

统计数据显示了典型的锯齿模式:在实例启动时,它会达到 190 - 210 Mb,然后在某些请求(但不是所有请求)时,内存使用量增加 20 - 30 Mb。(顺便说一下,这大致对应于查询结果的估计大小,虽然我不能确定这是相关信息。)这种情况一直发生,直到超过 512 Mb,当它被关闭时。它通常发生在对“/”的第 50 - 100 个请求左右。在此期间,不会对其他任何事物提出其他请求。

现在,如果我消除了“for”循环,只剩下查询,问题就会消失,内存使用量保持在 190 Mb,即使在 100 多个请求之后也没有增加。

最后的 gc.collect() 没有帮助。我还尝试查看函数开头和结尾处 tracemalloc 统计信息的差异,但没有发现任何有用的信息。

请问有人遇到过类似的吗?任何想法这里可能会出现什么问题?您可以推荐哪些额外的测试/调查?这可能是我无法控制的 Google App Engine/Datastore 问题吗?

谢谢你。

在此处输入图片说明

yed*_*tko 1

@Alex 在另一个答案中做了很好的研究,所以我将跟进这个建议:尝试使用NDB Library。对该库的所有调用都必须包装到上下文管理器中,这应该保证关闭后的清理工作。这可以帮助解决您的问题:

ndb_client = ndb.Client(**init_client)

with ndb_client.context():
    query = MyModel.query().order(MyModel.my_column)
    sources = query.fetch()
    for source in sources:
        pass

# if you try to query DataStore outside the context manager, it will raise an error
query = MyModel.query().order(MyModel.my_column)
Run Code Online (Sandbox Code Playgroud)