java - 使用 jdbc8.jar 和 Oracle 客户端 18 时 native 内存分配 (mmap) 无法映射

标签 java oracle oracle11g

我有一个 java 应用程序,它从 Oracle 11g 数据库版本 11.2.0.4.0(使用 spring 4)中提取大型 xml 并将它们存储在文件中。我们在提取包含多字节字符的数据时遇到问题。根据多字节在 xml 中的位置,有时会将多字节分成两部分。看来问题出在jdbc的版本和安装的oracle客户端上。因此,我们迁移到 Oracle 客户端 18 和 ojdb8.jar,保持代码不变。多字节问题已经解决,但现在我们遇到了以前没有发生过的内存问题。我得到的错误是:

内存不足,Java 运行时环境无法继续。

native 内存分配 (mmap) 无法映射 256376832 字节以提交保留内存。

我尝试过使用 java 命令参数,但没有效果。这就是我正在运行的: java -Dfile.encoding=UTF8 -Doracle.jdbc.timezoneAsRegion=false -Xmx10240m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp -XX:NativeMemoryTracking=detail -XX:+StartAttachListener -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMTStatistics

将 Xmx 减少到 512m 最终会耗尽堆内存。

我使用 jcmd VM.native_memory benchmark/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 为何对内存消耗影响如此之大?

最佳答案

内存问题已通过使用 xmlserialize 而不是 Oracle Java XMLType 对象得到解决。仍然使用Oracle客户端18和ojdbc8.jar。多字节 UTF8 分割不再有问题。

关于java - 使用 jdbc8.jar 和 Oracle 客户端 18 时 native 内存分配 (mmap) 无法映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56257884/

相关文章:

java - Java 选项 -Xmx 代表什么?

java - 在数字第一次出现时分割字符串的最有效方法?

java - Liferay 工作流程与 Kaleo : use custom class on task

sql - Oracle和sql server分页以及通用分页方法

oracle - 我可以通过某种方式从 dbms_scheduler 作业获取返回值吗?

java - 将正则表达式的匹配部分插入到替换文本中

sql - Oracle (+) 常数值运算符

java - 使用statement.executeQuery编写的Select语句无法选择具有-(破折号)的值

java - Oracle 数据库更改通知仅每 15 分钟发送一次

oracle - 强制查询 v$session_longops