Google应用程序引擎java OutOfMemoryError在memcache上putAll时出错
我在GAE memchace上存储了一张大约20k条目的地图。每个入口大约1Kb大。 我得到以下错误。有限制吗?据我所知,1Mb的限制是针对放入memcache中的每个实体,而不是整个批次Google应用程序引擎java OutOfMemoryError在memcache上putAll时出错,java,google-app-engine,google-cloud-datastore,Java,Google App Engine,Google Cloud Datastore,我在GAE memchace上存储了一张大约20k条目的地图。每个入口大约1Kb大。 我得到以下错误。有限制吗?据我所知,1Mb的限制是针对放入memcache中的每个实体,而不是整个批次 java.lang.OutOfMemoryError: Java heap space at com.google.appengine.repackaged.com.google.protobuf.AbstractMessageLite.toByteArray(AbstractMessageLite.java
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环境中,而不是在本地环境中
有任何帮助/提示吗?memcache的大小在GAE中完全是一个黑盒子。不要相信这是什么。你是对的,没有一个实体可以大于1MB,但是你不知道你的memcache总量有多大,也不知道驱逐策略是什么
GAE的最新版本似乎让我们对memcache有了一些了解,但到目前为止,它确实是一个黑匣子。我建议不要做你想做的事。如果需要预热缓存,请循环运行,只加载最相关的内容。memcache的大小在GAE中完全是一个黑匣子。不要相信这是什么。你是对的,没有一个实体可以大于1MB,但是你不知道你的memcache总量有多大,也不知道驱逐策略是什么
GAE的最新版本似乎让我们对memcache有了一些了解,但到目前为止,它确实是一个黑匣子。我建议不要做你想做的事。如果需要预热缓存,请在循环中进行,只加载最相关的内容。您会遇到异常,因为Java servlet容器内存不足,而不是因为与memcache相关的任何内容
但是,如果您试图在一个请求中设置20000个memcache密钥,我怀疑您做错了。您遇到异常是因为Java servlet容器内存不足,而不是因为与memcache相关的任何内容
但是,如果您试图在一个请求中设置20000个memcache密钥,我怀疑您做错了。您使用的是Appstats吗?我发现Appstats使用了大量内存,请参见我的问题: 我在尝试一次加载大约20000个条目时遇到了OutOfMemoryError,其大小与您的相似。现在我分批加载,每次加载1000个。下面是使用Siena的示例代码,但移植到其他ORM应该很容易: 我发现使用方法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>
你在使用Appstats吗?我发现Appstats使用了大量内存,请参见我的问题: 我在尝试一次加载大约20000个条目时遇到了OutOfMemoryError,其大小与您的相似。现在我分批加载,每次加载1000个。下面是使用Siena的示例代码,但移植到其他ORM应该很容易: 我发现使用方法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>
这似乎不是memcache的问题。在将数据馈送到memcache之前,它正在被序列化,也就是当您超过堆的大小时。如果您的实体大小为1k,这是令人惊讶的。实体中是否存在循环引用?这似乎不是memcache问题。在将数据馈送到memcache之前,它正在被序列化,也就是当您超过堆的大小时。如果您的实体大小为1k,这是令人惊讶的。实体中是否存在周期性引用?1kb的20k实体使其最大为20Mb,我认为这并没有那么大。它是?“我不能把它都放在memcache里吗?”@planadecu当然可以,但你仍然在说一次请求就可以写20000条记录。这不仅仅是总大小的问题。1kb的20k实体使其最大容量达到20Mb,我认为这并没有那么大。它是?“我不能把它都放在memcache里吗?”@planadecu当然可以,但你仍然在说一次请求就可以写20000条记录。这不仅仅是总尺寸的问题。