У меня проблемы с эффективностью. Я разрабатываю корпоративное приложение, которое развертывается на сервере JBoss EAP 6.1 как архив EAR. Я создаю новые объекты на основе сущностей в цикле while и записываю их в файл. Я получаю эти объекты (с помощью EJB DAO) в ограниченном количестве (например, 2000 для каждого шага). Проблема в том, что мне нужно обрабатывать миллионы объектов, и первый миллион идет довольно гладко, но дальнейшая петля идет медленнее, чем работает. Может ли кто-нибудь сказать мне, почему это работает медленнее и медленнее по мере продвижения циклы? Как я могу заставить его работать плавно всю дорогу? Вот некоторые важные части кода:
public void createFullIndex(int stepSize) {
int logsNumber = systemLogDao.getSystemLogsNumber();
int counter = 0;
while (counter < logsNumber) {
for (SystemLogEntity systemLogEntity : systemLogDao.getLimitedSystemLogs(counter, stepSize)) {
addDocument(systemLogEntity);
}
counter = counter + stepSize;
}
commitIndex();
}
public void addDocument(SystemLogEntity systemLogEntity) {
try {
Document document = new Document();
document.add(new NumericField("id", Field.Store.YES, true).setIntValue(systemLogEntity.getId()));
document.add(new Field("resource", (systemLogEntity.getResource() == null ? "" : systemLogEntity
.getResource().getResourceCode()), Field.Store.YES, Field.Index.ANALYZED));
document.add(new Field("operationType", (systemLogEntity.getOperationType() == null ? "" : systemLogEntity
document.add(new Field("comment",
(systemLogEntity.getComment() == null ? "" : systemLogEntity.getComment()), Field.Store.YES,
Field.Index.ANALYZED));
indexWriter.addDocument(document);
} catch (CorruptIndexException e) {
LOGGER.error("Failed to add the following log to Lucene index:\n" + systemLogEntity.toString(), e);
} catch (IOException e) {
LOGGER.error("Failed to add the following log to Lucene index:\n" + systemLogEntity.toString(), e);
}
}
Буду признателен за вашу помощь!
Насколько я вижу, вы не пишете свои материалы, насколько можете. Вместо этого вы пытаетесь создать полный объект DOM, а затем очистите его до файла. Эта стратегия хороша для ограниченного количества объектов. В вашем случае, когда вам приходится иметь дело с миллионами из них (как вы сказали), вы не должны использовать DOM. Вместо этого вы должны иметь возможность создавать свои XML-фрагменты и записывать их в файл во время получения данных. Это уменьшит потребление памяти и, надеюсь, улучшит производительность.
Я бы попробовал повторно использовать объект Document. У меня были проблемы с циклом с сборкой мусора, где мои циклы слишком быстрые, чтобы gc мог нормально идти в ногу, и повторное использование объектов решило все мои проблемы. Я не пробовал повторно использовать объект Document лично, но если это возможно, это может сработать для вас.
Ведение журнала должно быть легким. Использование добавления Guava в текст выглядит так:
File to = new File("C:/Logs/log.txt");
CharSequence from = "Your data as string\n";
Files.append(from, to, Charsets.UTF_8);
Немногие мои заметки: