谷歌ndb库内存泄漏
我想“ndb”库有内存泄漏,但我找不到在哪里。
有没有办法避免下面描述的问题?
你有更准确的测试方法来找出问题所在吗
是?
我就是这样再现这个问题的:
我用2个文件创建了一个极简的Google应用程序引擎。
附录yaml
:
application: myapplicationid
version: demo
runtime: python27
api_version: 1
threadsafe: yes
handlers:
- url: /.*
script: main.APP
libraries:
- name: webapp2
version: latest
main.py
:
# -*- coding: utf-8 -*-
"""Memory leak demo."""
from google.appengine.ext import ndb
import webapp2
class DummyModel(ndb.Model):
content = ndb.TextProperty()
class CreatePage(webapp2.RequestHandler):
def get(self):
value = str(102**100000)
entities = (DummyModel(content=value) for _ in xrange(100))
ndb.put_multi(entities)
class MainPage(webapp2.RequestHandler):
def get(self):
"""Use of `query().iter()` was suggested here:
https://code.google.com/p/googleappengine/issues/detail?id=9610
Same result can be reproduced without decorator and a "classic"
`query().fetch()`.
"""
for _ in range(10):
for entity in DummyModel.query().iter():
pass # Do whatever you want
self.response.headers['Content-Type'] = 'text/plain'
self.response.write('Hello, World!')
APP = webapp2.WSGIApplication([
('/', MainPage),
('/create', CreatePage),
])
我上传了一个名为“/create”的应用程序。
之后,每次对/
的调用都会增加实例使用的内存。直到
由于错误“超出了128 MB的软专用内存限制,它将停止
总共为5个请求提供服务后为143 MB。
注意:这个问题可以用“webapp2”以外的其他框架重现,
就像网页.py
-
经过更多的调查,在谷歌工程师的帮助下,我发现
对我的记忆力消耗的两种解释。
上下文和线程
ndb.上下文
是一个“线程本地”对象,只有在新的
请求进入线程。所以线程在请求之间保持它。很多
线程可能存在于一个GAE实例中,它可能需要数百个请求
在第二次使用线程并清除其上下文之前。
这不是内存泄漏,但内存中的上下文大小可能超过
小GAE实例中的可用内存。
解决方法:
不能配置GAE实例中使用的线程数。的确如此
最好使每个上下文尽可能小。避免上下文缓存,并清除
每次请求后都会被删除。
事件队列
NDB似乎不能保证事件队列在一个
请求。同样,这不是内存泄漏。但它在你的生活中留下了未来
线程上下文,回到第一个问题。
解决方法:
将所有使用NDB的代码包装为@ndb.toplevel公司
.