我有一个应用程序,它对外部API进行了许多异步调用,以获取有关图像缩略图的详细信息,以便在用户滚动浏览时将其加载到我的RecyclerView(使用Glide)中。 Recyclerview是“永无止境的”,因为如果用户想要滚动足够长的时间,则可能要加载数千个图像。
滚动查看一百张图像后出现以下错误:
W/Adreno-GSL: <gsl_ldd_control:541>:ioctl fd 55 code 0xc0200933 (IOCTL_KGSL_TIMESTAMP_EVENT) failed: errno 24 Too many open files
<ioctl_kgsl_syncobj_create:3977>: (38, 1f, 3907) fail 24 Too many open files
E/Parcel: fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 0, fds[i] is -1, fd_count is 1, error: Too many open files
I/Adreno: DequeueBuffer: dequeueBuffer failed
E/NativeCrypto: AppData::create pipe(2) failed: Too many open files
该应用程序永不崩溃,但一直保持冻结状态,直到我(稍等片刻?然后)退出该应用程序并返回到该应用程序。
从我所做的研究中,我了解到一次可以打开多少个文件是有限制的,但是我不确定如何控制它。
答案 0 :(得分:2)
当项目在屏幕上不可见时,您应该取消api调用和其他异步工作。 因为如果用户快速滚动,您将运行数百个无用的任务。
因此,只需在滚动视图时取消任务即可。
您可以使用RecylerView的void onViewRecycled (VH holder)
方法完成所有这些工作。
摘自文档:
void onViewRecycled (VH holder)
由该适配器创建的视图被回收后调用。
当RecyclerView.LayoutManager决定视图被回收时,该视图将被回收 不再需要附加到其父级RecyclerView。这可以是 因为它已失去可见性或一组缓存的视图 由仍附加到父级RecyclerView的视图表示。如果 项目视图具有绑定到的大型或昂贵数据,例如大型 位图,这可能是释放这些资源的好地方。
RecyclerView在清除ViewHolder的之前立即调用此方法 内部数据并将其发送到RecycledViewPool。这样,如果 ViewHolder在回收之前保存了有效信息,您 可以调用getAdapterPosition()来获取其适配器位置。
答案 1 :(得分:0)
我相信您要做的就是下载文件后关闭连接/套接字:
Socket accept - "Too many open files"
如果要缓存下载的图像,则还应正确关闭>>> period_subset_data
SP500 NASDAQ US20
1999-08-02 0.004698 -0.005727 0.000751
1999-08-03 -0.005810 -0.007322 -0.002250
... ... ... ...
2015-04-22 0.002943 0.002129 -0.011747
[4103 rows x 3 columns]
>>> facmat
SP500 NASDAQ US20
1999-08-02 0.979367 0.670188 1.696232
1999-08-03 0.979367 0.670188 1.696232
... ... ... ...
2015-04-21 0.979367 0.670188 1.696232
2015-04-22 0.979367 0.670188 1.696232
[4103 rows x 3 columns]
或>>> norm_returns
SP500 NASDAQ US20 (SP500,) (NASDAQ,) (US20,)
1999-08-02 NaN NaN NaN NaN NaN NaN
1999-08-03 NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ...
2015-04-21 NaN NaN NaN NaN NaN NaN
2015-04-22 NaN NaN NaN NaN NaN NaN
[4103 rows x 6 columns]
在根视图被破坏的同时也取消注册适配器:
FileInputStream