嗨,我有一个内存泄漏问题,我找不到任何解决办法。我的服务器代码:
bootstrap.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel socketChannel) throws Exception {
SSLEngine engine = engineCreator.createSSLEngine(credentials);
if (engine == null) {
throw new Exception("Can't create SSLEngine");
}
socketChannel.pipeline().addFirst("ssl", new SslHandler(engine));
socketChannel.pipeline().addLast("Object-decoder", new ObjectDecoder(
ClassResolvers.softCachingConcurrentResolver(
Message.class.getClassLoader())));
socketChannel.pipeline().addLast("Object-encoder", new ObjectEncoder());
//another pair of handles
}
})
.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
发动机创建者代码:
private static SSLEngine sslEngine = null;
public SSLEngine createSSLEngine(Credentials credentials) {
try {
if(sslEngine == null){
sslEngine = getSSLContext(credentials).createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(true);
}
return sslEngine;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private SSLContext getSSLContext(Credentials credentials) throws Exception {
InputStream keyStoreInputStream = new FileInputStream(credentials.getKeyStorePath());
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(keyStoreInputStream, credentials.getKeyStorePassword().toCharArray());
keyStoreInputStream.close();
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(keyStore, credentials.getKeyStorePassword().toCharArray());
TrustManager[] trustManagers = new TrustManager[]{
new ReloadableX509TrustManager(credentials)
};
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagers, null);
return sslContext;
}
class ReloadableX509TrustManager implements X509TrustManager {
private final String trustStorePath;
private X509TrustManager trustManager;
private long listTimeModTrust;
private final Credentials credentials;
public ReloadableX509TrustManager(Credentials credentials) throws Exception {
this.credentials = credentials;
this.trustStorePath = credentials.getTrustStorePath();
reloadTrustManager(credentials);
}
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws
CertificateException {
if (checkTimeTruststore()) {
try {
reloadTrustManager(credentials);
} catch (Exception e) {
e.printStackTrace();
}
}
String username = x509Certificates[0].getSubjectDN().getName().split("CN=")[1].split(",")[0];
x509Certificates[0].checkValidity();
trustManager.checkClientTrusted(x509Certificates, s);
x509Certificates[0].checkValidity();
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws
CertificateException {
// trustManager.checkServerTrusted(x509Certificates, s);
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
private void reloadTrustManager(Credentials credentials) throws Exception {
listTimeModTrust = new File(trustStorePath).lastModified();
KeyStore trustStore = KeyStore.getInstance("JKS");
InputStream in = new FileInputStream(trustStorePath);
try {
trustStore.load(in, credentials.getTrustStorePassword().toCharArray());
} finally {
in.close();
}
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance("SunX509");
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
for (int i = 0; i < trustManagers.length; i++) {
if (trustManagers[i] instanceof X509TrustManager) {
trustManager = (X509TrustManager) trustManagers[i];
return;
}
}
throw new NoSuchAlgorithmException("No X509TrustManager in TrustManagerFactory");
}
private boolean checkTimeTruststore() {
boolean isNewVersion = false;
File file = new File(trustStorePath);
Long lastTime = file.lastModified();
if (lastTime != listTimeModTrust) {
isNewVersion = true;
}
return isNewVersion;
}
}
我的信托店里面有2k证书。堆转储:eclipse内存泄漏插件的屏幕
目前,在服务器运行几天后,会发生outofmemoryexception,服务器已关闭。有人知道怎么修吗?
2条答案
按热度按时间yv5phkfx1#
我怀疑问题可能是你创造了一个新的
SslContext
每个连接的对象数。你应该创建一次,然后分享。w7t8yxp52#
你考虑过运行内存泄漏检测器吗?https://netty.io/wiki/reference-counted-objects.html
如果问题不是sslcontext,我怀疑它可能在
ObjectDecoder
或者ObjectEncoder
如果你不释放ByteBuf
当你完成它的时候。