2011-04-06 78 views
1

獲得了在AppEngine上運行的應用程序。一直運行良好2年。今天檢查它,我發現它失敗了。我很長一段時間都沒有碰過這些代碼。OutOfMemoryError:Java堆空間GoogleAppEngine

我得到的錯誤是這樣的:

java.lang.OutOfMemoryError: Java heap space 
at com.google.storage.onestore.v3.OnestoreEntity$Property.<init>(OnestoreEntity.java:2849) 
at com.google.storage.onestore.v3.OnestoreEntity$EntityProto.addProperty(OnestoreEntity.java:5755) 
at com.google.storage.onestore.v3.OnestoreEntity$EntityProto.merge(OnestoreEntity.java:6232) 
at com.google.apphosting.api.DatastorePb$QueryResult.merge(DatastorePb.java:13045) 
at com.google.appengine.repackaged.com.google.io.protocol.ProtocolMessage.mergeFrom(ProtocolMessage.java:405) 
at com.google.appengine.repackaged.com.google.io.protocol.ProtocolMessage.mergeFrom(ProtocolMessage.java:422) 
at com.google.appengine.repackaged.com.google.io.protocol.ProtocolMessage.parseFrom(ProtocolMessage.java:534) 
at com.google.appengine.api.datastore.DatastoreApiHelper$1.wrap(DatastoreApiHelper.java:90) 
at com.google.appengine.api.datastore.DatastoreApiHelper$1.wrap(DatastoreApiHelper.java:83) 
at com.google.appengine.api.utils.FutureWrapper.wrapAndCache(FutureWrapper.java:51) 
at com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:67) 
at com.google.appengine.api.datastore.FutureHelper.getInternal(FutureHelper.java:71) 
at com.google.appengine.api.datastore.FutureHelper.quietGet(FutureHelper.java:32) 
at com.google.appengine.api.datastore.QueryResultsSourceImpl.loadMoreEntities(QueryResultsSourceImpl.java:69) 
at com.google.appengine.api.datastore.QueryResultsSourceImpl.loadMoreEntities(QueryResultsSourceImpl.java:56) 
at com.google.appengine.api.datastore.QueryResultIteratorImpl.ensureLoaded(QueryResultIteratorImpl.java:156) 
at com.google.appengine.api.datastore.QueryResultIteratorImpl.hasNext(QueryResultIteratorImpl.java:65) 
at org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator$1.get(RuntimeExceptionWrappingIterator.java:50) 
at org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator$1.get(RuntimeExceptionWrappingIterator.java:47) 
at org.datanucleus.store.appengine.query.QueryExceptionWrappers$1.get(QueryExceptionWrappers.java:51) 
at org.datanucleus.store.appengine.query.QueryExceptionWrappers$2.get(QueryExceptionWrappers.java:86) 
at org.datanucleus.store.appengine.query.RuntimeExceptionWrappingIterator.hasNext(RuntimeExceptionWrappingIterator.java:105) 
at org.datanucleus.store.appengine.query.LazyResult.resolveAll(LazyResult.java:115) 
at org.datanucleus.store.appengine.query.LazyResult.size(LazyResult.java:110) 
at org.datanucleus.store.appengine.query.StreamingQueryResult.size(StreamingQueryResult.java:130) 
at guestbook.ProxyServlet.processRequest(ProxyServlet.java:132) 
at guestbook.ProxyServlet.doGet(ProxyServlet.java:288) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:617) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:717) 
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511) 
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166) 
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97) 

的代碼在我的代理Servlet接入線路132我從數據庫retrived實體的名單。它是這一行「System.out.println(」from db「+ allEventsLst.size());」

我的應用程序在我運行本地服務器時起作用。有任何想法嗎???

String fromDateStr = shortDf.format(fromDate); 



    Query query = pm.newQuery(Event.class, "date >= fromDate"); 
     query.declareImports("import java.lang.String"); 
     query.declareParameters("String fromDate");  

    List<Event> allEventsLst = (List<Event>)query.execute(fromDateStr); 

    System.out.println("from db "+allEventsLst.size()); 

    Map<String, Event> eventMap = new HashMap<String, Event>(); 

    for (Event e : allEventsLst) { 

感謝

+0

您的數據集變得足夠大,不再適合可用內存了嗎? – 2011-04-06 18:30:16

+0

好的,我的壞。 appEngine版本沒有正確執行日期過濾,因此它正在獲取所有內容,因此內存不足。問題是我將日期保存爲實體中的字符串,並且由於客戶機依賴性,我無法更改它。我怎樣才能得到數據庫的日期大於我獲得日期的實體? – 2011-04-06 19:41:44

+0

你的日期格式是什麼?如果是ISO格式(yyyy-mm-dd),則可以過濾字符串並獲得預期結果。如果沒有,你運氣不好 - 你必須使用mapreduce來替換你的日期字符串與實際日期。 – 2011-04-07 01:56:56

回答

1

不能完全確定,但可能是因爲名單是延遲加載,當你調用大小的方法有加載的所有元素。由於你的應用程序已經運行了一段時間,它可能有足夠的元素來解決內存不足的問題。

+0

也許它在本地的數據庫是小的,日期測試不起作用,因此整個數據庫被加載到appengine中。 – 2011-04-06 19:12:46

0

檢查從源返回的行數。可能性是,有比正常情況更多的行,並且數據源沒有啓用遊標,所以驅動程序試圖將所有行加載到內存中,然後用完。

+0

這並不是一個大回報的結果。像10個項目。 – 2011-04-06 18:45:19

相關問題