java.lang.outofmemoryerror с обновлением firebase - PullRequest
0 голосов
/ 03 мая 2018

Я занимаюсь разработкой java spring приложения для анализа file размером около 220 Мб с 800 000 записей. Цель кода - поместить записи в базу данных Firebase. Проблема, с которой я сталкиваюсь,

Превышено ограничение jc.lang.outofmemoryerror gc

Этот код будет нормально выполняться первый или два раза, но последующие вызовы будут выполняться медленнее и приводят к ошибке нехватки памяти. Этот фрагмент кода будет работать без вызова обновления базы данных Firebase. Было замечено, что вызов обновления базы данных firebase не освобождает пространство кучи даже после завершения выполнения.

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 голосов
/ 03 мая 2018

Вы инициализируете itemjson в новый HashMap перед циклом while, но никогда не очищаете его до окончания цикла (если это не сделано в одном из вызванных методов, но у меня нет такого впечатления), то есть он будет продолжать расти для каждый раз через цикл.

Более того, вы вызываете updateChildrenAsync с itemjson в цикле, когда размер равен> batchsize, который всегда будет истинным после того, как он будет истинным в первый раз. Поэтому, если размер пакета равен 100, вы вызовете updateChildrenAsync, как только itemjason достигнет этого размера, а затем вызовите его снова один раз каждый раз в цикле с в основном теми же данными.

Очистка itemjason непосредственно после вызова updateChildrenAsync должна решить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...