gpt4 book ai didi

java - Tomcat 和垃圾收集数据库连接

转载 作者:行者123 更新时间:2023-11-28 22:39:22 24 4
gpt4 key购买 nike

我问(并自己回答)this question几天前,解决了这个问题,但我不太明白为什么问题得到解决,希望得到一些澄清。

基本上,我实现了一个基于 jax-rs 的 REST 服务,该服务从 RavenDB 数据库检索信息并以流的形式返回该内容。我遇到的问题是一个未关闭的数据库结果迭代器,它导致 REST 服务在恰好 10 个请求后挂起(并且不再接受进一步的请求)。

我的代码大致如下:

public Response ...
{
(...)

StreamingOutput adminAreaStream = new StreamingOutput()
{
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();

@Override
public void write(OutputStream output) throws IOException, WebApplicationException
{
try(IDocumentSession currentSession = ServiceListener.ravenDBStore.openSession())
{
Writer writer = new BufferedWriter(new OutputStreamWriter(output));
(...)
CloseableIterator<StreamResult<AdministrativeArea>> results;
(...)
writer.flush();
writer.close();
results.close();
currentSession.advanced().clear();
currentSession.close();
}
catch (Exception e)
{
System.out.println("Exception: " + e.getMessage() + e.getStackTrace());
}
}
};
if(!requestIsValid)
return Response.status(400).build();
else
return Response.ok(adminAreaStream).build();
}

根据我对 Java 中对象生命周期的理解,或者更具体地说,对象可达性和垃圾回收,即使我没有正确关闭 CleasableIterator,它也应该在我的方法完成时超出范围/变得不可访问具有 400 或 200 状态 - 因此得到垃圾收集。

明确一点:我当然不是建议人们不应该正确地关闭打开的连接等——我现在正在这样做——或者依赖 Java 的垃圾收集机制来避免我们懒惰/不干净的编码……我我只是在努力理解那些未关闭的迭代器是如何导致观察到的 Tomcat 行为的。

事实上,我的假设是我们甚至不需要知道迭代器实现的细节,因为在 Java 对象生命周期的“银河级”,实现差异是无关紧要的。 =>“一旦一个对象变得不可访问,它是如何编码的就无关紧要了”。我唯一能想象的就是 Tomcat 以某种方式(通过它的容器机制?),稍微改变了这里的游戏,并导致事情“徘徊”。有人可以阐明这一点吗?

提前致谢!

最佳答案

CloseableIterator 指的是 CloseableHttpResponse,它指的是 HTTP 连接。当 CloseableIterator 不再可用时,终结器不会释放响应或连接。您造成了连接泄漏。您的错误类似于此处描述的错误:https://phillbarber.blogspot.com/2014/02/lessons-learned-from-connection-leak-in.html

在这里查看为什么释放资源的终结方法不是一个好主意:https://www.baeldung.com/java-finalize

关于java - Tomcat 和垃圾收集数据库连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53528514/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com