我正在开发一个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();
}
}
答案 0 :(得分:0)
你在while循环之前将itemjson初始化为一个新的HashMap,但是在循环之后你永远不会清除它(除非这是在一个被调用的方法中完成但我没有得到那个印象)意味着它将继续通过循环每次都成长。
此外,当大小为&gt;时,您可以在循环中使用itemjson调用updateChildrenAsync。 batchsize在第一次出现之后将始终为true。因此,如果batchsize为100,那么一旦itemjason达到该大小,您将调用updateChildrenAsync,然后每次通过循环再次调用一次,其中大部分数据都相同。
调用updateChildrenAsync后直接清空itemjason可以解决问题。