使用LdapTemplate时,不会关闭LDAP连接

时间:2016-11-20 17:19:14

标签: java jndi spring-ldap

关闭Tomcat后,我们看到很多关于可能的内存泄漏的错误,因为Tomcat无法停止线程。 根据Tomcat,我们有〜2600个守护程序线程,它们在com.sun.jndi.ldap.Connection.pauseReader中等待。

我们正在使用LdapTemplate从LDAP读取数据。每次我们需要从LDAP读取数据时都会创建LdapTemplate。从文档中我看到搜索结束后LdapTemplate释放了所有资源。 我们没有为LdapTemplate启用池,默认为false。

调试后,看起来在搜索结束后不会立即销毁为Connection创建的线程,但最终会破坏部分线程。

知道我们为什么会有这么多的守护程序线程在com.sun.jndi.ldap.Connection.pauseReader上等待?

我们正在使用spring-ldap 2.0.2.RELEASE。

在执行搜索之前我们如何创建LdapTemplate的示例代码:

LdapContextSource contextSource = new LdapContextSource();
SimpleAuthenticationSource authenticationSource = new SimpleAuthenticationSource(userDn, password);
contextSource.setAuthenticationSource(authenticationSource);
LdapTemplate ldapTemplate = new LdapTemplate(contextSource);
ldapTemplate.setIgnorePartialResultException(true);

更新:  将设置合并为true后,连接将被释放。

ldapContextSource.setPooled(true); 

问题是我们不能使用池化。我仍然不明白为什么不使用池时没有正确释放Connections。

2 个答案:

答案 0 :(得分:0)

您提到您没有使用连接池,但这可能很好地解决了您在线程失控时遇到的问题。

Take a look here,了解如何通过PoolingContextSource的Spring XML配置配置LDAP连接池。 Here is another example如何使用基于注释的配置启用连接池。

请注意,文档专门提到在Spring LDAP中启用池,而不是通过"com.sun.jndi.ldap.connect.pool"属性在JDK中启用JNDI LDAP提供程序。

作为参考,以下是2013年的一个类似问题,它似乎启用连接池能够减少线程数量:https://github.com/spring-projects/spring-security/issues/2397

答案 1 :(得分:0)

经过大量调试后,问题是我们在其中一个查询中检索了上下文而没有关闭它:

ldapTemplate.getContextSource().getReadOnlyContext().getNameInNamespace()

我们在使用后没有关闭上下文。

关闭上下文解决了问题,修复后没有线程处于等待状态。