Мой Tomcat веб-приложение запрашивает SVN для фиксаций между двумя точками во времени:SVNKit утечка памяти: SVNLog.run() создает поток, который никогда не убил
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()
называется. Вы видите, что есть две группы: первая группа принадлежит предыдущему экземпляру webapp - который уже был остановлен - по какой-то причине они не убиваются вместе с webapp.
Стек след нити 6 и резьбы 11:
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()
Если я закомментировать log.run()
нити не создаются и, таким образом, никакие ресурсы не просочилась. Так что проблема в том, что log.run()
- как-то нить не убивается, когда webapp убит.
svnOperationFactory.dispose();
В конце кода, похоже, ничего не утилизируется.
Любая идея?
Я использую tomcat 8, svnkit 1.8.11, это все новейшие версии на сегодняшний день. –
Еще один немой вопрос: вы взяли кучи кучи между несколькими развертываниями, наблюдая за вновь созданными потоками после каждого развертывания, гарантируя, что это просто не проблема, когда несколько потоков создаются при первом/втором перераспределении? – entpnerd
Да, я потратил 2 дня на эти проблемы и сделал все трюки в книге - я уверен, что нити - это продукты SVNLog.run() –