解决办法
- 降低http请求的频率
- 针对Android 8.1.0,level 27 设备,做单独处理
- cancel掉多余的请求(待验证,后期再写结果)
结论
- 页面存在过多的 https 请求,每次申请ssl资源时,创建一个pipe,最后耗光了 可打开文件描述符的数量
- 明确 页面的https 资源消耗情况
- 是不是没有调用cancel?(原因看下文 4. OKHttp里用pipe )
我们是监听EditText输入,有文字变更就 https请求。可能某些情境下,突破了OkHttp的逻辑(socket的复用、https的复用了)。
Pipe相关
- 崩溃发生在创建pipe的系统调用时。
- pipe一般用于IPC通信。如Linux shell 将第一个命令输出,作为第二个命令输入。
adb logcat | grep "ActivityManager"
,其中 | 管道符号 ,就是用的pipe int fdArray[2]; pipe[fdArray];
fdArray文件描述符数组,fdArray[0]读,fdArray[1]写。然后调用IOwrite(fdArray[1], input_str, strlen(input_str)+1);
就可以通信了。源码- OKHttp里用pipe
- 取消connection ( 所以源码fd叫 fdsEmergency,紧急停止按钮):connection被 select()阻塞,select系统调用是 非阻塞IO调用(和Looper.loop的那个epoll一样),同时监听多个fd。(推测1个fd是某个io,io可读 connection继续往下走;1个fd 就是fdsEmergency[0] ,可读就是取消connection)
- 第二个用来解决 race condition(线程不安全里的 竞争条件,这个我就不翻译了太长)
* (3) The pipe is used primarily as a means of cancelling a blocking select()
* when we want to close the connection (aka "emergency button"). It is also
* necessary for dealing with a possible race condition situation: There might
* be cases where both threads see an SSL_ERROR_WANT_READ or
* SSL_ERROR_WANT_WRITE. Both will enter a select() with the proper argument.
* If one leaves the select() successfully before the other enters it, the
* "success" event is already consumed and the second thread will be blocked,
* possibly forever (depending on network conditions).
*
* The idea for so