Java SVNKit内存泄漏:SVNLog.run()创建从未终止的线程

Java SVNKit内存泄漏:SVNLog.run()创建从未终止的线程,java,tomcat,memory-leaks,svnkit,Java,Tomcat,Memory Leaks,Svnkit,我的Tomcat webapp在两个时间点之间查询SVN的提交: final SVNURL url = SVNURL.parseURIEncoded("svn+ssh://xxxx/xxxx/xxxx"); SVNSSHAuthentication sshCredentials = SVNSSHAuthentication.newInstance( Constants.SVN_USERNAME, Constants.PRIVATE_KEY, Constants.

我的Tomcat webapp在两个时间点之间查询SVN的提交:

    final SVNURL url = SVNURL.parseURIEncoded("svn+ssh://xxxx/xxxx/xxxx");

SVNSSHAuthentication sshCredentials = SVNSSHAuthentication.newInstance(
    Constants.SVN_USERNAME,
    Constants.PRIVATE_KEY,
    Constants.PRIVATE_KEY_PASS_PHRASE,
    Constants.SVN_PORT,
    Constants.ALLOW_CREDENTIALS_TO_BE_STORED,
    url,
    Constants.CREDENTIAL_IS_NOT_PARTIAL);

ISVNAuthenticationManager authManager = new BasicAuthenticationManager(new SVNAuthentication[] { sshCredentials });
SvnOperationFactory svnOperationFactory = new SvnOperationFactory();
try {

  svnOperationFactory.setAuthenticationManager(authManager);

  final SvnLog log = svnOperationFactory.createLog();
  log.addRange(SvnRevisionRange.create(SVNRevision.create(new Date(1444612639000l)), SVNRevision.create(new Date(1444737236000l))));
  log.setDiscoverChangedPaths(true);
  log.setLimit(100l);
  log.setReceiver(new ISvnObjectReceiver<SVNLogEntry>() {
    @Override
    public void receive(SvnTarget target, SVNLogEntry logEntry) throws SVNException {
      System.out.println(logEntry);
    }
  });
  log.setSingleTarget(SvnTarget.fromURL(url));
  log.run();
}
catch (SVNException e) {
  throw e;
} finally {
  svnOperationFactory.dispose();
}
如果我注释掉
log.run()
,则不会创建线程,因此不会泄漏任何资源。因此,问题是由于
log.run()
——当webapp被终止时,线程并没有被终止

svnOperationFactory.dispose()似乎没有处理任何内容


有什么想法吗?

根据我的经验,第三方软件中的漏洞实际上取决于版本。你的问题不是说你使用的是什么版本的SVNKit。所以作为响应的第一个破解,我会问你是否使用的是最新版本的SVNKit。我一直在使用SVNKit研究一些候选内存泄漏,包括:


  • 还有其他一些。但是,它们似乎都是针对SVNKit的旧版本的,所以如果可能的话,我会先尝试升级。

    我使用的是tomcat 8,SVNKit 1.8.11,它们都是迄今为止的最新版本。另一个愚蠢的问题:您是否在多个部署之间进行堆转储,在每次部署后观察新创建的线程,确保这不是在第一次/第二次重新部署时创建的线程很少的问题?是的,我花了2天时间讨论这个问题,并且完成了书中的每一个技巧-我确信这些线程是SVNLog.run()Fukuzawa的产品,我想你指的是类org.tmatesoft.svn.core.wc2.SVNLog,对吗?我下载了源代码,其中有两个类名SVNLog——这就是问题所在。@FukuzawaYukio,我在本地主机上查看了包的源代码。您提到您尝试了
    svnOperationFactory.dispose()
    ,但没有效果。您是否已尝试将
    log.cancel()
    添加到
    finally
    块或代码中其他更可取的位置?
    Thread dump at 5:11.060.359
    
    * Thread group "main":
    
      Thread "Thread-6":
        at java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[ ], int, int, int)
        at java.net.SocketInputStream.read(byte[ ], int, int, int)
        at java.net.SocketInputStream.read(byte[ ], int, int)
        at com.trilead.ssh2.crypto.cipher.CipherInputStream.fill_buffer()
        at com.trilead.ssh2.crypto.cipher.CipherInputStream.internal_read(byte[ ], int, int)
        at com.trilead.ssh2.crypto.cipher.CipherInputStream.getBlock()
        at com.trilead.ssh2.crypto.cipher.CipherInputStream.read(byte[ ], int, int)
        at com.trilead.ssh2.transport.TransportConnection.receiveMessage(byte[ ], int, int)
        at com.trilead.ssh2.transport.TransportManager.receiveLoop()
        at com.trilead.ssh2.transport.TransportManager$1.run()
        at java.lang.Thread.run()