How can I resolve a "java.lang.OutOfMemoryError: Java heap space" for the Map property timeseries that's apparently too big to retrieve from the Google App Engine datastore? The error occurs when I try to read the entity containing the large map from the datastore using an Objectify load() operation.
Here's the entity containing the large Map:
@com.googlecode.objectify.annotation.Entity
public class Insight {
@com.googlecode.objectify.annotation.Id
public Long id;
@Stringify(com.netbase.model.DateStringifier.class)
public Map<Date, Double> timeseries;
}
Here is the Stringifier implementation:
public class DateStringifier implements Stringifier<Date> {
@Override
public String toString(Date obj) {
return Long.toString(obj);
}
@Override
public Date fromString(String str) {
long timestamp_long = Long.parseLong(timestamp);
Date date = new Date(timestamp_long);
return date;
}
}
I've already tried running this in a Google Module with the largest memory size (Instance Class B8 as described at https://cloud.google.com/appengine/docs/java/modules/).
I've also tried using cursors, thinking garbage collection would happen after ever cursor refresh. But I'm actually get the exception on the very first cursor with a cursor size of 1, suggesting that a single Map itself is too big.
I'm not sure how I was able to persist such a large map in the first place but it happened weeks ago and the logs are lost now. It was an expensive operation to build the Map so I'd like to see if I can still retrieve it.
Since it was persisted with Objectify, I'm not sure how to read it with the underlying datastore. Any advice on how to resolve this would be most appreciated.
============================================================
Update: I managed to get my data out of Google App Engine by exporting it in pieces. I'm not sure how I managed to do it when the original problem seemed like it would have prevented me.
At any rate, I wanted to update you guys and let you know that the total amount of data was 23.5 MB of data. It's about 6K entities, each of which has the Map<Date, Double> timeseries. That means each entity had about 3.9 MB of data. According to @stickfigure in his solution below, that's about the limit of how big an Entity can be. So I will have to figure out some way to break the Entities up into smaller ones and process the data in separate sessions. I'm kind of disappointed because I thought Google App Engine would give me a lot more resources. I figure, if I can hold 23.5 MB in an Excel file and Excel on my local machine can process this much data without trouble, then Google App Engine should be able to handle many times more.