Oracle XMLType和BinXMLProcCache导致内存泄漏




我对Oracle数据库缺乏经验,但现在我正在调查一个有趣的问题
我认为XMLType类使用的BinXMLProcCache对象中存在T4C连接泄漏的问题
谷歌说他对这两个关键词一无所知:XMLType"BinXMLProcCache"内存泄漏,所以我在这里寻求帮助。简而言之,问题细节:Spring的JdbcTemplate用于处理数据源。Oracle ojdbc6 11.2.0.3.0,xdb6 11.2.0.3.1。

public SomeDoc store(Document doc) throws DataAccessException, JAXBException {
    XMLType xmlType = null;
    Connection connection = null;
    SomeDoc someDoc = null;
    try {
        LOGGER.info(doc.toString());
        MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
                                     //I've hided some fields
        mapSqlParameterSource.addValue("F1", something, Types.VARCHAR);
        //... more fields
        StringWriter stringWriter = new StringWriter();
        Marshaller marshaller = jaxbContext.createMarshaller();
        marshaller.marshal(doc.getData(), stringWriter);
        String xml = stringWriter.toString();
        try {
            connection = dataSource.getConnection();
            OracleConnection oracleConnection = connection.unwrap(OracleConnection.class);
            xmlType = XMLType.createXML(oracleConnection, xml);
        } catch (SQLException e) {
            LOGGER.error(e.getMessage(), e);
            throw new UncategorizedSQLException("XML conversion error", "", e);
        }
        mapSqlParameterSource.addValue("FIELDS", xmlType);
        //... and some more fields
        namedParameterJdbcTemplate.update(SQL_STORE, mapSqlParameterSource);
        someDoc = namedParameterJdbcTemplate.queryForObject(SQL_GET_DOC_BY_REF,
                new MapSqlParameterSource("DOC_REF", doc.getDoc_ref()), someDocRowMapper);
    } finally {
        if (xmlType != null) {
            try {
                xmlType.free();
            } catch (SQLException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                LOGGER.error(e.getMessage(), e);
            }
        }
        if (xmlType != null) {
            xmlType.close();
        }
    }
    return someDoc;
}

我已经使用EclipseMAT查看了堆转储的内容,并注意到了一些有趣的情况:内存中有很多T4C连接。未来的调查让我看到了这张照片:https://www.dropbox.com/sh/izvvrys124xjb8l/AACGyIDg6c2miwjrIu8-aGH-a?dl=0(由于信誉不佳,我不能发布两个以上的链接,所以图片在我的dropbox相册中,对不起)
所以,我读过http://www.oracle.com/technetwork/topics/memory.pdf,现在我明白了Oracle的选择方式:用内存换取性能。

但我现在也在想,如果池驱逐空闲一段时间的连接(看看dbcp的minIdle和maxIdle选项),内存中会有一些新连接的增长。通过在内存中使用缓冲区来提高驱动程序性能,BinXMLProcCache会造成内存泄漏。关键是T4C连接,现在价值已经不重要了。BinXMLProcCache存储在XMLType的静态字段中,它存储WeakHashMap,这些键永远不会被清除,我认为它会造成内存泄漏
我的调查正确吗
提前感谢!

/*找到了我自己的问题,我会自己回答,因为这个问题有解决方案*/所以,问题确实出在Oracle的驱动程序上
来自Oracle网站:

Bug 17537657 oracle.XDB.SoftHashMap中XDB内存泄漏17537657的修复程序首先包含在12.2(未来版本)12.1.0.2(服务器修补程序集)12.1.0.1.4数据库修补程序集更新12.1.0.1 Windows平台上的修补程序11描述使用瘦驱动程序调用getDocument()或getBinXMLStream()时使用任何驱动程序,oracle.xdb.SoftHashMap类都会发生内存泄漏。BinXMLProcessorImpl类在此SoftHashMap中积累,但从未已删除

所以,只要应用Oracle的修复程序,问题就会消失。

最新更新