带有firebase更新的java.lang.outofmemoryerror

时间:2018-05-03 10:55:24

标签: java firebase firebase-realtime-database

我正在开发一个java spring应用程序来解析大约220 Mb大小的file,其中有800 000条记录。代码的目的是将记录推送到firebase数据库。 我面临的问题是

  

java.lang.outofmemoryerror超出gc开销限制

此代码将在前一次或两次运行正常,但后续调用将变慢并导致内存不足错误。此代码段在没有firebase db update调用的情况下可以正常工作。已经观察到firebase db update调用即使在完成执行后也没有释放堆空间。

fireDBRef = FirebaseDatabase.getInstance(FirebaseApp.getApps().get(0)).getReference(getEnvironment().getProperty(catalog_root_node));
BeanReader reader = getBeanReader("C:\\Users\\aneesh\\Desktop\\Feeds\\N01.S2.SWC.MGS2410.BAS.ATG");
CatalogDTO catalog = null;
int count = 0;
int clubNo = 0;
String clubItemRoot = "";
int currentSize = 0;
Map<String, Object> itemjason =  new HashMap<String, Object>();
int batchsize= Integer.parseInt(getEnvironment().getProperty(catalog_batch_size)) * Integer.parseInt(getEnvironment().getProperty(catalog_record_size));

while((catalog = (CatalogDTO) reader.read()) != null){
    if(null==itemjason){
        itemjason =  new HashMap<String, Object>();
    }
    if(!getFeedValidateManger().getFeedValidator(catalog_feed_type).isValidFeed(catalog)){
        logger.info("Catalog : Invalid Feed record format : "+ Integer.parseInt(catFeedArray[3]));
        continue;
    }
    clubNo = Integer.parseInt(catalog.getClubNo());
    clubItemRoot= clubNo+getEnvironment().getProperty(items_root_node)+catalog.getItemNo();
    getItemJsonPopertiesMap(itemjason,catalog,clubItemRoot);
    currentSize = itemjason.size();
    if(itemjason!=null && !itemjason.isEmpty() && currentSize>=batchsize)
    {
        fireDBRef.updateChildrenAsync(itemjason);
    }
    System.out.println(count++);
}
if(null!=itemjason && itemjason.size()<batchsize && itemjason.size()>0)
{
    firebaseService.updateFeedsToFirebase(fireDBRef, itemjason);
    itemjason = null;
}
logger.info(lineNum + " lines of catalog feeds written");
updateTracker(FeedInfoStatus.SUCCESS, "Sent records: " + getSuccessCount());
sendNotification();

} 
catch (Exception e) {
    logger.error(e.getMessage());
    String msg = e.getMessage();
    updateTracker(FeedInfoStatus.FAILED, msg.length() >= MSG_MAX_LENGTH ? msg.substring(0, MSG_MAX_LENGTH - 1)
                       : msg);
    sendNotification();
}finally{
    fireDBRef = null;
    System.gc();
}
}

1 个答案:

答案 0 :(得分:0)

你在while循环之前将itemjson初始化为一个新的HashMap,但是在循环之后你永远不会清除它(除非这是在一个被调用的方法中完成但我没有得到那个印象)意味着它将继续通过循环每次都成长。

此外,当大小为&gt;时,您可以在循环中使用itemjson调用updateChildrenAsync。 batchsize在第一次出现之后将始终为true。因此,如果batchsize为100,那么一旦itemjason达到该大小,您将调用updateChildrenAsync,然后每次通过循环再次调用一次,其中大部分数据都相同。

调用updateChildrenAsync后直接清空itemjason可以解决问题。