由于克隆的客户端,OkHttp连接泄漏

时间:2018-07-02 07:12:19

标签: java okhttp

我正在研究与Okhttp连接泄漏有关的issue。泄漏堆栈跟踪似乎指向此WebSocket连接正在PodOperationsImpl#L267中打开:

        try {
            URL url = new URL(URLUtils.join(getResourceUrl().toString(), sb.toString()));
            Request.Builder r = new Request.Builder().url(url).header("Sec-WebSocket-Protocol", "v4.channel.k8s.io").get();
            OkHttpClient clone = client.newBuilder().readTimeout(0, TimeUnit.MILLISECONDS).build();
            final ExecWebSocketListener execWebSocketListener = new ExecWebSocketListener(getConfig(), in, out, err, errChannel, inPipe, outPipe, errPipe, errChannelPipe, execListener);
            clone.newWebSocket(r.build(), execWebSocketListener);
            execWebSocketListener.waitUntilReady();
            return execWebSocketListener;
        } catch (Throwable t) {
            throw KubernetesClientException.launderThrowable(forOperationType("exec"), t);
        }

运行问题本身提供的测试时,我在日志上看到连接泄漏消息:

WARNING: A connection to http://localhost:48271/ was leaked. Did you forget to close a response body?
java.lang.Throwable: response.body().close()

但是,当我从一个新实例创建OkHttpClient而不是从上一个实例克隆它时,这些连接泄漏警告减少了3/4。克隆客户端是否容易出现连接泄漏?还是我做的方式不正确?有什么方法可以确保我们能够处理这些连接泄漏警告消息?

还有一件事情,使用ExecWebSocketListener打开了websocket,它已经实现了AutoCloseable。尽管从调用方进行try-with-resources似乎可以避免这些警告。但是我不确定它是否真的在解决泄漏的根本原因。

1 个答案:

答案 0 :(得分:0)

该克隆无关。此警告依赖于垃圾收集器在关闭实例之前找到超出范围的实例,并且该过程既非立即执行,也不是特别可靠。