private void logSoapMessage(SOAPMessage soapMessage, String type) {
ByteArrayOutputStream bout = null;
try {
bout = new ByteArrayOutputStream();
soapMessage.writeTo(bout);
logger.info("The " + type + " is " + bout.toString("UTF-8"));
} catch (IOException e) {
logger.debug("Exception while logging soap message " + e);
}
}
上面的代码会出现资源泄漏错误吗?
上面的代码会出现资源泄漏错误吗?
这不是资源泄漏。不在 Java 8 中,或者(AFAIK)在任何其他版本中。 (这也不是内存泄漏。)
A
ByteArrayOutputStream
没有任何可能泄漏的资源1。事实上,close()
上的 ByteArrayOutputStream
的 documentation表明它没有任何效果。
但是,不成熟的静态检查器可能错误地将您的代码标记为潜在的资源泄漏。您可以以适当的方式将其标记为“误报”,或者直接关闭流。以下是针对 Java 7 及更高版本执行后者的最佳方法:
try (ByteArrayOutputStream bout = new ByteArrayOutputStream()) {
soapMessage.writeTo(bout);
logger.info("The " + type + " is " + bout.toString("UTF-8"));
} catch (IOException e) {
logger.debug("Exception while logging soap message " + e);
}
请注意,“泄漏”保护并不是绝对必要的。我们这样做只是为了阻止检查人员向我们提供虚假报告。
1 - 资源是指从操作系统获取的诸如文件描述符之类的东西,并且通常数量有限。如果 Java 应用程序未正确管理这些资源,则应用程序可能会耗尽这些资源。持有资源的对象通常会实现
AutoClosable
并提供 close()
方法来释放资源。这些对象通常会使用终结器或清理器或类似的方法来清理泄漏的资源。然而,这可能不足以防止出现问题;例如取决于 GC 是否足够快地将对象识别为无法访问以触发清理。
这是因为您在使用完资源后没有关闭该资源。
Java 7 引入了 try-with-resource 函数:
private void logSoapMessage(SOAPMessage soapMessage, String type) {
try (ByteArrayOutputStream bout = new ByteArrayOutputStream()){
soapMessage.writeTo(bout);
logger.info("The " + type + " is " + bout.toString("UTF-8"));
} catch (IOException e) {
logger.debug("Exception while logging soap message " + e);
}
}
即使抛出异常,也会自动关闭
ByteArrayOutputStream
。
java 7 之前的旧方法你必须这样写:
private void logSoapMessage(SOAPMessage soapMessage, String type) {
ByteArrayOutputStream bout = null;
try {
bout = new ByteArrayOutputStream();
soapMessage.writeTo(bout);
logger.info("The " + type + " is " + bout.toString("UTF-8"));
} catch (IOException e) {
logger.debug("Exception while logging soap message " + e);
} finally {
if (bout != null) bout.close();
}
}
确保在退出方法之前关闭资源并且不会发生资源泄漏。
以下是有关 try-with-resource 的一些信息: https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html