-1

J'ai un projet GAE écrit en Python. J'ai fait un cron pour exécuter une opération par lots. Mais il a atteint une limite de mémoire privée de l'instance F1, qui est de 124 Mo après quelques itérations. Quelqu'un pourrait-il m'aider à écrire ce code de manière plus efficace, avec un peu moins de 124 Mo. len (personnes) doit être inférieur à 500.Une fuite de mémoire s'est produite dans le projet Google App Engine Python. Un moyen efficace d'écrire mon opération?

def cron(): 
    q = Account.all().filter('role =', 1) 
    people = [e for e in q] 
    for p in people: 
     s = Schedule.available(p) 
     m = ScheduleMapper(s).as_dict() 
     memcache.set('key_for_%s' % p.key(), m) 

Ceci est un serveur de développement et je ne souhaite pas mettre à niveau ma classe d'instance. De plus, je veux éviter d'utiliser des bibliothèques tierces, telles que numpy et pandas.

J'ai ajouté un garbage collection dans la dernière ligne de for boucle. Mais cela ne semble pas fonctionner.

del s 
m.clear() 
import gc 
gc.collect() 
+0

Vous n'avez pas mentionné le nombre d'entités que vous récupérez. En outre, je déplacerais la boucle vers une fonction et la gc vers l'extérieur. Quand vous parlez d'itérations, voulez-vous dire invocations du gestionnaire de cron ou de la boucle externe ou interne? –

+0

Merci pour le commentaire! Le nombre d'entités devrait être inférieur à 500. Quant aux itérations, je parlais de boucle interne. – steve

+0

combien sur la boucle interne. Sans voir vos modèles, je soupçonne que vous détenez des références quelque part. –

Répondre

0

Pour voir s'il est même possible de l'intégrer dans l'empreinte mémoire que vous souhaitez modifier votre requête pour obtenir une seule entité et vérifier si vous pouvez exécuter avec succès la boucle for pour cette seule entité. Ou tout simplement ajouter un break à la fin de la boucle for :)

Si cela ne fonctionne pas, vous besoin de votre classe mise à niveau d'instance. Si l'expérience fonctionne, vous pouvez diviser le travail en utilisant Query Cursors en plusieurs tâches push queue, chacune traitant une seule entité ou seulement quelques-unes d'entre elles. Peut-être jeter un coup d'œil à Google appengine: Task queue performance pour une discussion sur la division du travail en plusieurs tâches (bien que la raison du fractionnement dans ce cas dépassait la date limite de la demande, pas la limite de la mémoire). Notez que même en utilisant plusieurs tâches, il est toujours possible d'atteindre la limite de mémoire (voir App Engine Deferred: Tracking Down Memory Leaks), mais au moins le travail serait effectué même si une instance particulière est redémarrée (les tâches sont réessayées par défaut).