Android NativeCrypto: AppData::create pipe(2) failed: Too many open files崩溃

Android Retrofit和OkHttpClient多实例+添加头部SharePreferences,进行频繁操作网络请求一段时间程序卡死崩溃问题的一些经历记录

一、bug复现:

viewpager+FragmentStatePagerAdapter+fragment+MVP,不断滑动翻页并频繁进行网络请求导致卡死。

二、原因猜测&修复尝试:

1.bug出现后第一感觉认为是fragment重复创建导致内存泄漏,然后尝试了viewpager的setOffsceenPageLimit设置,也尝试了viewpager中getItem使用fragment.newInstance()的方式创建fragment。然而崩溃还是一样存在!

2.之后以为是mvp中presenter强引用导致的内存泄漏,尝试将BasePresenter中的view引用改为WeakReference弱引用,将BasePresenter中的状态做了优化,创建初始化、销毁前属性对象等都反初始化,结果还是没解决。

3.最后根据报错的日志判断是我封装的MVP网络请求库内出了问题,报错如下:

2019-08-26 15:12:38.709 31527-31659/com.xxx E/NativeCrypto: AppData::create pipe(2) failed: Too many open files
2019-08-26 15:12:38.710 31527-31527/com.xxx D/DareLove-XObserver: │ onError()		function : dynamic/xxx request error, reason : socket already closed
2019-08-26 15:12:38.710 31527-31527/com.xxx D/DareLove-XObserver: │ onError()		function : dynamic/xxx request error, reason : javax.net.ssl.SSLException: Unable to create application data
2019-08-26 15:12:38.899 31527-31537/com.xxx E/System: Uncaught exception thrown by finalizer
2019-08-26 15:12:38.900 31527-31537/com.xxx E/System: java.net.SocketException: socket already closed
        at java.net.PlainSocketImpl.socketClose0(PlainSocketImpl.java:211)
        at java.net.AbstractPlainSocketImpl.socketClose(AbstractPlainSocketImpl.java:721)
        at java.net.AbstractPlainSocketImpl.close(AbstractPlainSocketImpl.java:546)
        at java.net.SocksSocketImpl.close(SocksSocketImpl.java:554)
        at java.net.AbstractPlainSocketImpl.finalize(AbstractPlainSocketImpl.java:619)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:255)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:242)
        at java.lang.Daemons$Daemon.run(Daemons.java:108)
        at java.lang.Thread.run(Thread.java:764)
2019-08-26 15:12:38.900 31527-31537/com.xxx E/System: Uncaught exception thrown by finalizer
2019-08-26 15:12:38.900 31527-31537/com.xxx E/System: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean com.android.org.conscrypt.SslWrapper.isClosed()' on a null object reference
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.free(ConscryptFileDescriptorSocket.java:986)
        at com.android.org.conscrypt.ConscryptFileDescriptorSocket.finalize(ConscryptFileDescriptorSocket.java:1014)
        at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:255)
        at java.lang.Daemons$FinalizerDaemon.runInternal(Daemons.java:242)
        at java.lang.Daemons$Daemon.run(Daemons.java:108)
        at java.lang.Thread.run(Thread.java:764)

三、经过一系列分析得出结果:

NativeCrypto: AppData::create pipe(2) failed: Too many open files  意思我大概理解为文件打开太多。再根据我的复现操作大概能判断是okhttp retrofit异常导致,经过一番折腾,找到问题所在为retrofit和okhttp每一次请求都创建新的实例,并且在请求的头部都拿本地存储在SharePreferences的token和其他信息,因此导致频繁请求的时候实例太多文件打开太多而崩溃。

如果你也遇到这样的异常,请检查是否存不正确的姿势:

1.Retrofit对象是否每次网络请求都进行了实例化新的对象(此处包括OkHttpClient的多实例使用)。

2.Interceptor中的intercept方法添加请求头部的时候,是否每次都到本地SharePreferences获取token等信息。

四、解决办法:

用同一个Retrofit和OkHttpClient实例,并且将头部信息存于内存中(用属性承接),当需要请求不同的服务器地址以及添加不同头部的时候才进行第二个Retrofit和OkHttpClient实例的初始化。

 

你可能感兴趣的:(Android,Retrofit,okhttp,fragment,android)