Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.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 Netty:DefaultChannelHandlerContext的内存泄漏问题_Java_Ssl_Memory Leaks_Netty - Fatal编程技术网

Java Netty:DefaultChannelHandlerContext的内存泄漏问题

Java Netty:DefaultChannelHandlerContext的内存泄漏问题,java,ssl,memory-leaks,netty,Java,Ssl,Memory Leaks,Netty,嗨,我有一个内存泄漏问题,我找不到任何解决方案。我的服务器代码: bootstrap.channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override protected void initChannel(SocketChannel socketChann

嗨,我有一个内存泄漏问题,我找不到任何解决方案。我的服务器代码:

 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);
bootstrap.channel(NioServerSocketChannel.class)
.childHandler(新的通道初始值设定项(){
@凌驾
受保护的无效初始化通道(SocketChannel SocketChannel)引发异常{
SSLEngine engine=engineCreator.CreateSLengine(凭证);
如果(引擎==null){
抛出新异常(“无法创建SSLEngine”);
}
socketChannel.pipeline().addFirst(“ssl”,新的SslHandler(引擎));
socketChannel.pipeline().addLast(“对象解码器”,新的对象解码器(
ClassResolver.softCachingConcurrentResolver(
Message.class.getClassLoader());
socketChannel.pipeline().addLast(“对象编码器”,新对象编码器());
//另一对把手
}
})
.option(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT)
.childOption(ChannelOption.ALLOCATOR,PooledByteBufAllocator.DEFAULT);
EngineCreator的代码:

 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;
    }

}
private static SSLEngine SSLEngine=null;
公共SSLEngine CreateSLengine(凭据){
试一试{
if(sslEngine==null){
sslEngine=getSSLContext(凭证).createSSLEngine();
sslEngine.setUseClientMode(false);
sslEngine.setNeedClientAuth(true);
}
返回sslEngine;
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
私有SSLContext getSSLContext(凭据)引发异常{
InputStream keyStoreInputStream=新文件InputStream(credentials.getKeyStorePath());
KeyStore KeyStore=KeyStore.getInstance(“JKS”);
load(keyStoreInputStream,credentials.getKeyStorePassword().toCharArray());
keyStoreInputStream.close();
KeyManagerFactory KeyManagerFactory=KeyManagerFactory.getInstance(“SunX509”);
init(keyStore,credentials.getKeyStorePassword().toCharArray());
TrustManager[]TrustManager=新的TrustManager[]{
新的可重新加载X509TrustManager(凭据)
};
SSLContext SSLContext=SSLContext.getInstance(“TLSv1.2”);
sslContext.init(keyManagerFactory.getKeyManagers(),trustManagers,null);
返回sslContext;
}
类ReloadableX509TrustManager实现X509TrustManager{
私有最终字符串信任存储路径;
私人X509TrustManager trustManager;
私人长期信托;
私人最终证书;
public ReloadableX509TrustManager(凭据)引发异常{
this.credentials=凭证;
this.trustStorePath=credentials.getTrustStorePath();
重新加载信任管理器(凭据);
}
@凌驾
public void checkClientTrusted(X509Certificate[]x509Certificates,字符串s)抛出
证书例外{
if(checkTimeTruststore()){
试一试{
重新加载信任管理器(凭据);
}捕获(例外e){
e、 printStackTrace();
}
}
字符串用户名=x509Certificates[0]。getSubjectDN().getName().split(“CN=”)[1]。split(“,”[0];
X509证书[0]。检查有效性();
trustManager.checkClientTrusted(x509Certificates,s);
X509证书[0]。检查有效性();
}
@凌驾
public void checkServerTrusted(X509Certificate[]x509Certificates,字符串s)抛出
证书例外{
//trustManager.checkServerTrusted(x509Certificates,s);
}
@凌驾
公共X509证书[]getAcceptedIssuers(){
返回新的X509证书[0];
}
private void reloadTrustManager(凭据)引发异常{
listTimeModTrust=新文件(trustStorePath).lastModified();
keystoretruststore=KeyStore.getInstance(“JKS”);
InputStream in=新文件InputStream(trustStorePath);
试一试{
load(在中,credentials.getTrustStorePassword().toCharray());
}最后{
in.close();
}
TrustManagerFactory TrustManagerFactory=TrustManagerFactory.getInstance(“SunX509”);
init(信任库);
TrustManager[]TrustManager=trustManagerFactory.GetTrustManager();
for(int i=0;i
我的信任商店里有2k份证书。堆转储:


目前,在服务器运行几天后,OutOfMemoryException发生,服务器关闭。有人知道如何修复它吗?

我怀疑问题可能是您为每个连接创建了一个新的
SslContext
对象。您应该创建一次,然后共享它。

您考虑过运行内存泄漏检测器吗?


如果问题不是sslContext,我怀疑它可能在
ObjectDecoder
ObjectEncoder
中,如果您在使用
ByteBuf
时没有释放它。

问题是必须为每个连接创建sslContext。我使用SSLContext和不使用SSLContext是两个不同的类。我不认为这是真的。。。必须为每个连接SSLContex创建SSLEngine