Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Tomcat和垃圾收集数据库连接_Java_Tomcat_Garbage Collection_Jax Rs_Database Connection - Fatal编程技术网

Java Tomcat和垃圾收集数据库连接

Java Tomcat和垃圾收集数据库连接,java,tomcat,garbage-collection,jax-rs,database-connection,Java,Tomcat,Garbage Collection,Jax Rs,Database Connection,几天前我问了(并回答了我自己),解决了这个问题,但我不太明白为什么这个问题被解决了,希望得到一些澄清 本质上,我实现了一个基于jax-rs的REST服务,该服务从RavenDB数据库检索信息并以流的形式返回该内容。我遇到的问题是一个未关闭的数据库结果迭代器,它导致REST服务在恰好10个请求之后挂起(并且不接受进一步的请求) 我的代码大致如下: public Response ... { (...) StreamingOutput adminAreaSt

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

本质上,我实现了一个基于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();
    }
公众响应。。。
{
(...)
StreamingOutput adminAreaStream=新的StreamingOutput()
{
ObjectWriter ow=新建ObjectMapper().writer().withDefaultPrettyPrinter();
@凌驾
public void write(OutputStream output)引发IOException、WebApplicationException
{
try(IDocumentSession currentSession=ServiceListener.ravenDBStore.openSession())
{
Writer Writer=new BufferedWriter(new OutputStreamWriter(output));
(...)   
可关闭迭代器结果;
(...)
writer.flush();
writer.close();
结果:关闭();
currentSession.advanced().clear();
currentSession.close();
}
捕获(例外e)
{
System.out.println(“异常:+e.getMessage()+e.getStackTrace());
}
}
};
如果(!requestIsValid)
返回Response.status(400.build();
其他的
返回Response.ok(adminAreaStream.build();
}
根据我对Java中对象生命周期的理解,或者更确切地说是对象可访问性和垃圾收集,即使我没有正确关闭该CleasableIterator,但在我的方法以400或200状态完成时,它应该超出范围/变得不可访问-因此得到垃圾收集

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

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


提前谢谢

CloseableIterator指的是一个
CloseableHttpResponse
,它指的是一个HTTP连接。当
CloseableIterator
不再可访问时,没有终结器释放响应或连接。您创建了一个连接泄漏。您的bug与此处描述的bug类似:


请参见此处为什么最终确定释放资源的方法是一个坏主意:
CloseableIterator
指的是一个
CloseableHttpResponse
,它指的是一个HTTP连接。当
CloseableIterator
不再可访问时,没有终结器释放响应或连接。您创建了一个连接泄漏。您的bug与此处描述的bug类似:


看看这里为什么最终确定释放资源的方法是个坏主意:

谢谢-这正是正在发生的事情。。。那么,公平地说,在我的场景中,这归结为我的http连接在Tomcat中耗尽的事实吗?这很奇怪,因为数字10看起来“非常人性化”——在我的server.xml中,我找不到10的明确限制(既不是maxConnections,也不是maxThreads)!如果没有特别说明,这是否意味着?请看这里:
HttpClientBuilder HttpClientBuilder=HttpClientBuilder.custom().setMaxConnPerRoute(10)它被硬编码到RavenDB客户端。您可以通过设置
RequestExecutor.configureHttpClient
来更改该值。在我看来,这不是一个非常干净的解决方案…RavenDB Java客户端库管理自己的HTTP连接(通过Apache HttpComponents库),并使用一个内部连接池,该连接池独立于您可以在Tomcat中配置的任何内容。下面是…@chromanoid的完美答案-非常感谢!我有一种预感,那是Tomcat无法控制的事情…谢谢-这正是正在发生的事情。。。那么,公平地说,在我的场景中,这归结为我的http连接在Tomcat中耗尽的事实吗?这很奇怪,因为数字10看起来“非常人性化”——在我的server.xml中,我找不到10的明确限制(既不是maxConnections,也不是maxThreads)!如果没有特别说明,这是否意味着?请看这里:
HttpClientBuilder HttpClientBuilder=HttpClientBuilder.custom().setMaxConnPerRoute(10)它被硬编码到RavenDB客户端。您可以通过设置
RequestExecutor.configureHttpClient
来更改该值。在我看来,这不是一个非常干净的解决方案…RavenDB Java客户端库管理自己的HTTP连接(通过Apache HttpComponents库),并使用一个内部连接池,该连接池独立于您可以在Tomcat中配置的任何内容。下面是…@chromanoid的完美答案-非常感谢!我有一种预感,那是Tomcat无法控制的事情。。。