Привет, спасибо за ваш ответ. Подробнее: Импорт: я импортирую большой файл CSV для обработки и хранения в базе данных. Размер файла: размер файла составляет около 1,5 ГБ, содержит около 20 миллионов строк, каждая из которых имеет 9 полей. Обработка: данные проверяются, преобразуются в объекты Person и пакетно вставляются в базу данных. Потоковая передача: использование BufferedReader для построчной обработки файла с помощью API Java Streams. Размер пакета: уменьшено до 20 записей в пакете, но ошибка OutOfMemoryError по-прежнему возникает. JVM: работает с ограничением памяти -Xmx200m.
Код: Выделить всё
@Transactional
public void processCsvFile(Path pathToFile, int processId) {
int batchSize = 40;
List
batch = new ArrayList(batchSize);
AtomicInteger processedRows = new AtomicInteger();
long startTime = System.nanoTime();
try (Stream personDtoStream = csvFileReaderService.readCsvFile(pathToFile)) {
personDtoStream.forEach(personDto -> {
try {
personValidationService.validatePersonDto(personDto);
Person person = mappingFacade.mapToPerson(personDto);
batch.add(person);
if (batch.size() == batchSize) {
personBatchService.saveBatch(batch);
batch.clear();
System.gc();
}
processedRows.getAndIncrement();
if (processedRows.get() % 100000 == 0) {
processStatusService.updateProcessedRows(processId, processedRows.get());
}
} catch (RuntimeException e) {
log.error("Error processing CSV data: " + e.getMessage(), e);
processStatusService.updateStatus(processId, ProcessStatusEnum.FAILED, processedRows.get(), e.getMessage());
throw e;
}
});
if (!batch.isEmpty()) {
personBatchService.saveBatch(batch);
}
частный финальный PersonParserRegistry parserRegistry;
Код: Выделить всё
@Transactional
public Stream
readCsvFile(Path pathToFile) throws IOException {
BufferedReader bufferedReader = Files.newBufferedReader(pathToFile);
return bufferedReader.lines().skip(1)
.map(this::parseCsvToPersonDto)
.filter(Objects::nonNull);
}
private PersonDto parseCsvToPersonDto(String line) {
try {
String[] personProperties = line.split(",");
if (personProperties.length < 9) {
log.warn("Invalid CSV data format: Expected at least 9 fields, but got {}", personProperties.length);
return null;
}
String type = personProperties[0].trim();
PersonParser parser = parserRegistry.findParser(type);
if (parser == null) {
log.warn("No parser found for type: {}", type);
return null;
}
log.debug("Parsing line: {}", line);
return parser.parse(personProperties);
} catch (Exception e) {
log.error("Error parsing CSV line: {} - {}", line, e.getMessage());
return null;
}
}
Подробнее здесь: https://stackoverflow.com/questions/788 ... mory-issue