Ich denke, es gibt einen Speicherverlust in der ndb
-Bibliothek, aber ich kann nicht finden, wo.Speicherleck in Google Ndb-Bibliothek
Gibt es eine Möglichkeit, das unten beschriebene Problem zu vermeiden?
Haben Sie eine genauere Vorstellung von Tests, um herauszufinden, wo das Problem liegt?
Das ist, wie ich das Problem reproduziert:
I mit 2 Dateien eine minimalistische Google App Engine-Anwendung erstellt.
app.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),
])
ich die Anwendung hochgeladen, rief einmal /create
.
Danach erhöht jeder Aufruf von /
den von der Instanz verwendeten Speicher. Bis es wegen des Fehlers Exceeded soft private memory limit of 128 MB with 143 MB after servicing 5 requests total
stoppt.
Exemple von Diagramm zur Speicherauslastung (Sie können das Speicherwachstum und Abstürze sehen):
Hinweis: Das Problem kann mit einem anderen Rahmen als webapp2
, wie web.py
wohl [ndb in-context-Cache] (https://cloud.google.com/appengine/docs/python/ndb/cache) erwarte ich. –
Ich weiß nichts über Python, aber wenn ich Ihren Code lese, würde ich sagen, dass Ihnen der Speicher ausgeht, weil Ihre 'ndb.put_multi' versucht, 100 Entitäten in einer einzigen Transaktion einzufügen. Das verursacht wahrscheinlich, dass viel Speicher zugewiesen wird. Das Überschreiten des Grenzwerts für den privaten Speicher ist wahrscheinlich darauf zurückzuführen, dass Ihre Transaktionen noch ausgeführt werden, wenn die nächste Anforderung zur Speicherauslastung hinzugefügt wird. Dies sollte nicht auftreten, wenn Sie zwischen den Anrufen eine Weile warten (bzw. warten, bis die Transaktion abgeschlossen ist). Außerdem sollte App Engine eine zusätzliche Instanz starten, wenn die Antwortzeiten drastisch ansteigen. – konqi
@DanielRoseman "Der In-Kontext-Cache bleibt nur für die Dauer eines einzelnen Threads bestehen." Wenn Sie den Kontextcache löschen oder eine Richtlinie zum Deaktivieren der Zwischenspeicherung festlegen, erhöht sich die Speicherbelegung langsamer, das Leck bleibt jedoch bestehen. – greg