当memAache上的putAll时,Google App Engine java OutOfMemoryError

时间:2012-04-01 19:11:48

标签: java google-app-engine google-cloud-datastore

我在GAE记忆中存储了大约20k个条目的地图。每个条目大约1Kb。 我收到以下错误。有限制吗?根据我的理解,1Mb的限制是你在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 个答案:

答案 0 :(得分:2)

内存缓存的大小是GAE中的一个黑盒子。不要相信它是什么。你是对的,没有一个实体可以大于1 MB,但你没有IDEA你的总memcache有多大,你也不知道驱逐政策是什么。

GAE的最新版本似乎让我们对memcache有了一些了解,但到目前为止,它确实是一个黑盒子。我建议不要做你想做的事。如果您需要加热缓存,请在循环中执行此操作,并仅加载最相关的内容。

答案 1 :(得分:1)

你得到一个异常是因为你的Java servlet容器内存不足,而不是因为与memcache相关的任何内容。

如果你试图在一个请求中设置20,000个memcache密钥,我怀疑你做错了。

答案 2 :(得分:1)

您使用的是Appstats吗?我发现Appstats使用了大量内存,请在此处查看我的问题: How to reduce the memory usage of Appstats on Google App Engine Java

我尝试一次加载大约20,000个条目时遇到OutOfMemoryError,与您的大小相似。现在我分批加载它们,当时是1000。以下是使用Siena的示例代码(但应该很容易移植到其他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>