2012-04-01 5 views
1

Ich speichere eine Karte von etwa 20k Einträge auf GAE memchace. Jeder Eintrag ist um 1Kb groß. Ich erhalte den folgenden Fehler. Gibt es eine Einschränkung? In meinem Verständnis der Begrenzung von 1 MB ist es für jede Entität, die Sie in den Memcache nicht die gesamte Charge setzen.Google App Engine java OutOfMemoryError wenn putAll auf Memcache

java.lang.OutOfMemoryError: Java heap space 
at com.google.appengine.repackaged.com.google.protobuf.AbstractMessageLite.toByteArray(AbstractMessageLite.java:34) 
at com.google.appengine.api.memcache.MemcacheServiceApiHelper.makeAsyncCall(MemcacheServiceApiHelper.java:104) 
at com.google.appengine.api.memcache.AsyncMemcacheServiceImpl.doPutAll(AsyncMemcacheServiceImpl.java:521) 
at com.google.appengine.api.memcache.AsyncMemcacheServiceImpl.putAll(AsyncMemcacheServiceImpl.java:564) 
at com.google.appengine.api.memcache.MemcacheServiceImpl.putAll(MemcacheServiceImpl.java:112) 
[...] 

Und mein Code wie folgt aussieht:

final HashMap<EntityToStoreKey, EntityToStore> map = new HashMap<EntityToStoreKey, EntityToStore>(); 
for (EntityToStore entityToStore : entitiesToStore) { 
    index.add(entityToStore); 
    map.put(EntityToStoreKey.key(entityToStore.getId(), false), entityToStore); 
} 
entityToStoreCache.putAll(map, portalCacheTimeout); 

Und das Problem nur auf einer prod Umwelt geschieht, nicht in lokalen.

Irgendwelche Hilfe/Tipp?

+0

Dies scheint kein 'memcache' Thema. Bevor die Daten an Memcache übergeben werden, wird sie serialisiert, und das ist der Fall, wenn Sie die Größe Ihres Heapspeichers überschreiten. Wenn Ihre Entitäten 1k groß sind, ist das überraschend. Könnte es einen zyklischen Bezug innerhalb der Entität geben? – cheeken

Antwort

1

Verwenden Sie Appstats? Ich habe festgestellt Appstats einen großen Teil des Speichers verwendet, meine Frage hier sehen: How to reduce the memory usage of Appstats on Google App Engine Java

ich OutOfMemoryError erlebt haben, wenn sie versuchen auf einmal rund 20.000 Einträge zu laden, ähnlich groß wie bei Ihnen. Jetzt lade ich sie in Stapeln, 1000 zu der Zeit. Hier ist ein Beispiel-Code Siena mit (aber es sollte auf andere ORMs zu portieren leicht): http://groups.google.com/group/siena-discuss/msg/cd874589ef7aaa66

ich praktisch finde die Methode List.subList() zu verwenden, gefolgt von List.remove() oder List.clear()

[Update]

ich einen undokumentierten Parameter gefunden haben, die die Größe von Stacktrace begrenzt:

<filter> 
    <filter-name>appstats</filter-name> 
    <filter-class>com.google.appengine.tools.appstats.AppstatsFilter</filter-class> 
    <init-param> 
     <param-name>maxLinesOfStackTrace</param-name> 
     <param-value>16</param-value> 
    </init-param> 
</filter> 
2

Die Größe von Memcache ist eine vollständige Black Box in GAE. Traue ihm nicht, irgendetwas zu sein. Sie sind richtig, keine einzelne Entität kann größer als 1 MB sein, aber Sie haben KEINE IDEE, wie groß Ihr gesamter Memcache ist, und Sie haben auch keine Ahnung, was die Vertreibungspolitik ist.

Die neueste Version von GAE scheint uns einige Einblicke in Memcache zu geben, aber bis jetzt war es wirklich eine Blackbox. Ich empfehle, nicht das zu tun, was Sie tun wollen. Wenn Sie Ihren Cache aufwärmen müssen, tun Sie dies in einer Schleife und laden Sie nur den relevantesten Inhalt.

1

Sie erhalten eine Ausnahme, weil in Ihrem Java-Servlet-Container nicht genügend Arbeitsspeicher zur Verfügung steht, nicht wegen Memcache.

Wenn Sie versuchen, 20.000 Memcache-Schlüssel in einer einzigen Anforderung festzulegen, vermute ich, dass Sie Doing It Wrong tun.

+0

20k Einheiten von 1kb macht es 20MB max, ich denke nicht, dass das so groß ist. Ist es ? Kann ich nicht alles im Memcache haben? –

+0

@planadecu Sicher, Sie können, aber Sie sprechen immer noch über das Schreiben _20.000_ Datensätze in einer einzigen Anfrage. Es geht nicht nur um die Gesamtgröße. –