我对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的修复程序,问题就会消失。