-
最近有个需求:需求循环请求一个接口,不管成功或失败都需要三秒请求一次,结果就造成了一个我一脸懵逼的异常。用了几天的时间在查这个异常android java.lang.RuntimeException Could not read input channel file descriptors from parcel.这个异常不会定位到具体错误的位置,也没有规律
-
最后查 查 查。原因是句柄泄露:
1)内存堆栈满了,没有多余的内存空间
2)进程创建的线程数量超过了进程的最大限制数量
3)进程的文件操作符数量超过了进程的最大限制数量
一个进程拥有的最大句柄数一般是1024,一旦超过这个值,该进程就会出现句柄泄露,进而引发一些报错情况。
在linux中一个文件、一个串口、一个socket、一个线程都可以是一个文件,而一个文件会占用一个句柄,linux中一个进程默认的句柄最大数值是1024,当超过这个数值,linux就会对当前的进程进行kill,而kill的对象可以是任意对象,所以会造成各种异常原因的崩溃。
第一个是查出来项目下Fd目录下的东西,其中socket会不中断增加,我把循环中的请求注释掉试试(命令可以去下面几个链接看)。第二个注释掉请求的时候,果然不会在增加了,当时我就纳闷了,明明失败和成功后都call.cancel(),后来我尝试重复用new Callback结果不行,用call.clone克隆结果不行,抓狂中........那就彻底写个请求,草泥马崩腾而过
-
结果:retrofit2+OkHttp+RxJava的请求中的call.cancel()(应该是retrofit2的)onFailure失败的时候(我这失败是接口404了)还会请求三次(封装请求的问题)没释放底层的Socket(我的理解)所以才会一直增加,释放销毁的速度赶不上创建的速度
http://www.voidcn.com/article/p-vxycvfib-brr.html
https://blog.csdn.net/qq_33617079/article/details/82316606