Connection pool and File handles

旧时模样 提交于 2019-11-29 03:59:48

问题


We use Retrofit/OkHttp3 for all network traffic from our Android application. So far everything seems to run quite smoothly.

However, we have now occasionally had our app/process run out of file handles.

  • Android allows for a max of 1024 file handles per process
  • OkHttp will create a new thread for each async call
  • Each thread created this way will (from our observation) be responsible for 3 new file handles (2 pipes and one socket).

We were able to debug this exactly, where each dispached async call using .enqueue() will lead to an increase of open file handles of 3.

The problem is, that the ConnectionPool in OkHttp seems to be keeping the connection threads around for much longer than they are actually needed. (This post talks of five minutes, though I haven't seen this specified anywhere.)

  • That means if you are quickly dispatching request, the connection pool will grow in size, and so will the number of file handles - until you reach 1024 where the app crashes.

I've seen that it is possible to limit the number of parallel calls with Dispatcher.setMaxRequests()(although it seems unclear whether this actually works, see here) - but that still doesn't quite address the issue with the open threads and file handles piling up.

How could we prevent OkHttp from creating too many file handles?


回答1:


I am answering my own question here to document this issue we had. It took us a while to figure this out and I think others might encounter this too and might be glad for this answer.


Our problem was that we created one OkHttpClient per request, as we used it's builder/interceptor API to configure some per-request parameters like HTTP headers or timeouts.

By default each OkHttpClient comes with its own connection pool, which of course blows up the number of connections/threads/file handles and prevents proper reuse in the pool.

Our solution

We solved the problem by manually creating a global ConnectionPool in a singleton, and then passing that to the OkHttpClient.Builder object which build the actual OkHttpClient.

  • This still allows for per-request configuration using the OkHttpClient.Builder
  • Makes sure all OkHttpClient instances are still using a common connection pool.

We were the able to properly size the global connection pool.



来源:https://stackoverflow.com/questions/42948985/connection-pool-and-file-handles

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!