我们对来自Android应用程序的所有网络流量使用Retrofit / OkHttp3。到目前为止,一切似乎都很顺利。
但是,我们现在偶尔会让我们的应用程序/进程耗尽文件句柄。
我们能够准确地调试这一点,其中每个使用
.enqueue()
进行的异步调用将导致打开文件句柄增加3。
问题是,OkHttp中的ConnectionPool
似乎将连接线程保持的时间比实际需要的时间长得多。 (This post谈了五分钟,虽然我没有在任何地方看到这个。)
我已经看到可以使用Dispatcher.setMaxRequests()
限制并行呼叫的数量(尽管似乎不清楚这是否真的有效,请参阅here) - 但这仍然无法解决打开线程和文件句柄堆积的问题。
我们怎么能阻止OkHttp创建太多文件句柄?
答案 0 :(得分:6)
我在这里回答我自己的问题来记录我们遇到的这个问题。我们花了一段时间来解决这个问题,我认为其他人也可能会遇到这种情况,并且可能对此答案感到高兴。
我们的问题是我们为每个请求创建了一个OkHttpClient
,因为我们使用它的构建器/拦截器API来配置一些每个请求参数,例如HTTP标头或超时。
默认情况下,每个OkHttpClient
都有自己的连接池,这当然会破坏连接/线程/文件句柄的数量,并阻止在池中正确重用。
我们通过在单例中手动创建全局ConnectionPool
,然后将其传递给构建实际OkHttpClient.Builder
的{{1}}对象来解决问题。
OkHttpClient
OkHttpClient.Builder
实例仍在使用公共连接池。我们能够正确调整全局连接池的大小。