Google App Engine java OutOfMemoryError, когда положить все в memcache - PullRequest
1 голос
/ 01 апреля 2012

Я храню карту около 20 тысяч записей в памяти GAE. Каждая запись размером около 1 КБ. Я получаю следующую ошибку. Есть ли ограничение? В моем понимании, ограничение в 1 Мб - это для каждой сущности, которую вы помещаете в 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)
[...]

И мой код выглядит так:

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);

И проблема возникает только в среде prod, а не в локальной.

Любая помощь / совет?

Ответы [ 3 ]

2 голосов
/ 01 апреля 2012

Размер memcache - это общий черный ящик в GAE.Не верь, что это что-то.Вы правы, ни один объект не может быть больше 1 МБ, но у вас НЕТ ИДЕИ, насколько велик ваш общий memcache, и вы не имеете ни малейшего представления о том, какова политика выселения.

Последняя версия GAE, кажется, дает нам некоторую прозрачность в memcache, но до сих пор это действительно был черный ящик.Я рекомендую не делать то, что вы пытаетесь сделать.Если вам нужно прогреть кеш, делайте это в цикле и загружайте только наиболее релевантный контент.

1 голос
/ 15 мая 2012

Вы используете Appstats? Я обнаружил, что Appstats использует большой кусок памяти, см. Мой вопрос здесь: Как уменьшить использование памяти Appstats в Google App Engine Java

Я столкнулся с OutOfMemoryError, когда пытался загрузить около 20 000 записей одновременно, размером с ваш. Теперь я загружаю их порциями по 1000 штук. Вот пример кода с использованием Сиены (но его легко перенести на другие ORM): http://groups.google.com/group/siena-discuss/msg/cd874589ef7aaa66

Мне удобно использовать метод List.subList (), за которым следует List.remove () или List.clear ()

[Обновление]

Я нашел недокументированный параметр, ограничивающий размер StackTrace:

<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>
1 голос
/ 02 апреля 2012

Вы получаете исключение, потому что у вашего контейнера сервлетов Java заканчивается память, а не из-за чего-либо, связанного с memcache.

Если вы пытаетесь установить 20 000 ключей memcache в одном запросе, хотяЯ подозреваю, что ты делаешь это неправильно.

...