У меня есть Java-приложение, которое извлекает большой XML-файл из базы данных Oracle 11g Release 11.2.0.4.0 (с использованием Spring 4) и сохраняет их в файлах. У нас возникла проблема при извлечении данных, содержащих многобайтовые символы. В зависимости от того, где в xml находится многобайтовый код, он иногда делит мультибайт на 2 части. Похоже, проблема была в версии jdbc и установленном клиенте oracle. Поэтому мы перешли на клиент Oracle 18 и ojdb8.jar, оставив код без изменений. Многобайтовая проблема была решена, но теперь вместо этого у нас есть проблемы с памятью, которых раньше не было. Я получаю ошибку:
Недостаточно памяти для продолжения среды выполнения Java.
При выделении собственной памяти (mmap) не удалось сопоставить 256376832 байта для фиксации зарезервированной памяти.
Я поигрался с параметрами команды java, но безрезультатно. Это то, что я бегу:
java -Dfile.encoding = UTF8 -Doracle.jdbc.timezoneAsRegion = false -Xmx10240m -XX: + HeapDumpOnOutOfMemoryError -XX: HeapDumpPath = / tmp -XX: NativeMemoryTracking = detail -XX: + Учебное ядро -XT: НОТАЛИЯ-НОТАЛИЯ: -XNTXTXTX: +
Уменьшение Xmx до 512 м привело к исчерпанию кучи памяти.
Я контролировал память приложения, используя jcmd VM.native_memory baseline / summary.diff и GC.class_stats, и одним из крупнейших потребителей памяти являются объекты String. Я не смог разобраться в остальном.
sql:
ВЫБЕРИТЕ XML_DATA
ИЗ таблицы, где ....
Столбец xml_data определяется как:
XML_DATA NOT NULL SYS.XMLTYPE ДВОЙНОЕ ХРАНИЛИЩЕ
Отображение этого в Java для oracle.xdb.XMLType:
public List<XMLType> extractXmlDataList(String sqlExtractionQuery, Key key) {
MapSqlParameterSource namedSqlParams = createKeyParamMap(key);
List<XMLType> dataList = namedParameterJdbcTemplate.queryForList(sqlExtractionQuery, namedSqlParams, XMLType.class);
return dataList;
}
protected void extractXmlData(Key key) {
List<XMLType> xmlRecs = producerDao.extractXmlDataList(sqlExtractionQuery, patentKey);
if (xmlRecs != null && xmlRecs.size() > 0) {
for (XMLType xmlData : xmlRecs) {
String xmlText = xmlData.getStringVal();
//create nu.xom.Document
Builder parser = new Builder();
Document xmlDocument = parser.build(xmlText, null);
}
}
}
Как переход на клиент Oracle 18 и jdbc8.jar может так сильно повлиять на потребление памяти?