Firebase DB:应用程序打开了太多文件。一个进程中可用文件描述符的最大值默认为 1024
Posted
技术标签:
【中文标题】Firebase DB:应用程序打开了太多文件。一个进程中可用文件描述符的最大值默认为 1024【英文标题】:Firebase DB: Application has opened too many files. Maximum of available file descriptors in one process is 1024 in default 【发布时间】:2021-08-29 12:54:30 【问题描述】:我在 Firebase 中遇到以下错误。我的代码不会直接打开任何文件,但它可以与 HttpOK、WebRTC 和整体网络一起广泛使用。网络是否也使用文件描述符?由于我的代码没有引发错误,我很好奇如何修复它。我可以以某种方式查看打开的文件描述符的位置和位置吗? (然后我可以找到导致描述符泄漏的原因)。
2021-06-13 04:14:59.610 30892-30994/com.mafialab.mafia E/SQLiteDatabase: 打开数据库失败 '/data/user/0/com.mafialab.mafia/databases/google_app_measurement_local.db'。 android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(代码 2062):无法打开数据库 ################################################# ############### 错误代码:2062 (SQLITE_CANTOPEN_EMFILE) 原因:应用程序打开了太多文件。一个进程中可用文件描述符的最大值默认为 1024。 (未知错误(代码 2062):无法打开数据库) ################################################# ############### 在 android.database.sqlite.SQLiteConnection.nativeOpen(本机方法) 在 android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:262) 在 android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:205) 在 android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:649) 在 android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:255) 在 android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:222) 在 android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:1191) 在 android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:1146) 在 android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:861) 在 android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:729) 在 android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:310) 在 android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:254) 在 android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194) 在 com.google.android.gms.measurement.internal.zzef.getWritableDatabase(com.google.android.gms:play-services-measurement-impl@@19.0.0:1) 在 com.google.android.gms.measurement.internal.zzeg.zzo(com.google.android.gms:play-services-measurement-impl@@19.0.0:1) 在 com.google.android.gms.measurement.internal.zzeg.zzq(com.google.android.gms:play-services-measurement-impl@@19.0.0:6) 在 com.google.android.gms.measurement.internal.zzeg.zzi(com.google.android.gms:play-services-measurement-impl@@19.0.0:9) 在 com.google.android.gms.measurement.internal.zzjk.zzl(com.google.android.gms:play-services-measurement-impl@@19.0.0:6) 在 com.google.android.gms.measurement.internal.zzhw.zzu(com.google.android.gms:play-services-measurement-impl@@19.0.0:147) 在 com.google.android.gms.measurement.internal.zzhc.run(com.google.android.gms:play-services-measurement-impl@@19.0.0:1) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 com.google.android.gms.measurement.internal.zzfq.run(com.google.android.gms:play-services-measurement-impl@@19.0.0:6) 2021-06-13 04:14:59.619 30892-30994/com.mafialab.mafia E/FA: 开幕 本地数据库失败,删除并重新创建它 2021-06-13 04:14:59.622 30892-30994/com.mafialab.mafia W/SQLiteLog: (28) 失败 打开 “/data/user/0/com.mafialab.mafia/databases/google_app_measurement_local.db” 带有标志 (131138) 和 mode_t (0) 由于错误 (24) 2021-06-13 04:14:59.622 30892-30994/com.mafialab.mafia W/SQLiteLog: (28) 失败 打开 “/data/user/0/com.mafialab.mafia/databases/google_app_measurement_local.db” 带有标志 (131072) 和 mode_t (0) 由于错误 (24) 2021-06-13 04:14:59.622 30892-30994/com.mafialab.mafia E/SQLiteLog: (14) 不能 在 [4bb21d8205] 2021-06-13 04:14:59.622 的第 36170 行打开文件 30892-30994/com.mafialab.mafia E/SQLiteLog: (14) os_unix.c:36170: (24) 打开(/data/user/0/com.mafialab.mafia/databases/google_app_measurement_local.db)
2021-06-13 04:14:59.622 30892-30994/com.mafialab.mafia E/SQLiteLog: (1) 进程: Pid (30892) Uid (10190) Euid (10190) Gid (10190) Egid (10190) 2021-06-13 04:14:59.624 30892-30994/com.mafialab.mafia E/SQLiteDatabase: 打开数据库失败 '/data/user/0/com.mafialab.mafia/databases/google_app_measurement_local.db'。 android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误(代码 2062):无法打开数据库 ################################################# ############### 错误代码:2062 (SQLITE_CANTOPEN_EMFILE) 原因:应用程序打开了太多文件。一个进程中可用文件描述符的最大值默认为 1024。 (未知错误(代码 2062):无法打开数据库) ################################################# ############### 在 android.database.sqlite.SQLiteConnection.nativeOpen(本机方法) 在 android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:262) 在 android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:205) 在 android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:649) 在 android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:255) 在 android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:222) 在 android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:1191) 在 android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:1146) 在 android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:861) 在 android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:729) 在 android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:310) 在 android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:254) 在 android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:194) 在 com.google.android.gms.measurement.internal.zzef.getWritableDatabase(com.google.android.gms:play-services-measurement-impl@@19.0.0:9) 在 com.google.android.gms.measurement.internal.zzeg.zzo(com.google.android.gms:play-services-measurement-impl@@19.0.0:1) 在 com.google.android.gms.measurement.internal.zzeg.zzq(com.google.android.gms:play-services-measurement-impl@@19.0.0:6) 在 com.google.android.gms.measurement.internal.zzeg.zzi(com.google.android.gms:play-services-measurement-impl@@19.0.0:9) 在 com.google.android.gms.measurement.internal.zzjk.zzl(com.google.android.gms:play-services-measurement-impl@@19.0.0:6) 在 com.google.android.gms.measurement.internal.zzhw.zzu(com.google.android.gms:play-services-measurement-impl@@19.0.0:147) 在 com.google.android.gms.measurement.internal.zzhc.run(com.google.android.gms:play-services-measurement-impl@@19.0.0:1) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 com.google.android.gms.measurement.internal.zzfq.run(com.google.android.gms:play-services-measurement-impl@@19.0.0:6) 2021-06-13 04:14:59.625 30892-30994/com.mafialab.mafia E/FA: 未能 打开本地数据库。事件将绕过本地存储: android.database.sqlite.SQLiteCantOpenDatabaseException:未知错误 (代码 2062):无法打开数据库 ################################################# ############### 错误代码:2062 (SQLITE_CANTOPEN_EMFILE) 原因:应用程序打开了太多文件。一个进程中可用文件描述符的最大值默认为 1024。 (未知错误(代码 2062):无法打开数据库) ################################################# ###############: com.google.android.gms.measurement.internal.zzef.getWritableDatabase(com.google.android.gms:play-services-measurement-impl@@19.0 .0:9)
【问题讨论】:
在哪种情况下会出现此错误? (在启动时或运行时的某个时间)。一些使用应用程序的资源可以是文件:共享首选项、原始资源、资产、sqlite db、日志文件。可能是应用程序尝试以递归方式或循环方式启动一些分析。可能是当您的应用每次尝试保存(或读取)某些内容时,您会创建某个对象的新实例(如保存日志),该对象会打开文件而不是在完成后关闭文件。 这些都不适用。使用 webrtc 的应用程序,我强烈怀疑它相关。我的问题是如何检查运行时打开的处理程序的数量?如果我知道这一点,我可以找到代码的哪一部分导致它。我不直接在我的代码中使用文件或处理程序,但是 3rd 方库可以做到这一点 当我与多个参与者进行广泛的 webrtc 调用时会发生错误。但由于错误不是发生在 webrtc 本身,而是发生在 Firebase 中(可能是崩溃分析?),这会使调试过程复杂化 ***.com/questions/35557930/… 这个问题的答案怎么样? (一些库(组件)可以在单独的进程中启动 - 检查所有这些) 【参考方案1】:套接字(网络或管道)确实有文件描述符。
您可以列出它们:
for (f in File("/proc/self/fd").listFiles())
Log.i(TAG, "file : $f.isFile, $f -> $f.canonicalPath")
...
file : false, /proc/self/fd/50 -> /dev/kgsl-3d0
file : false, /proc/self/fd/51 -> /proc/2815/fd/51
file : false, /proc/self/fd/52 -> /proc/2815/fd/52
file : false, /proc/self/fd/53 -> /proc/2815/fd/53
file : false, /proc/self/fd/54 -> /proc/2815/fd/54
file : false, /proc/self/fd/55 -> /proc/2815/fd/55
file : false, /proc/self/fd/56 -> /proc/2815/fd/56
file : false, /proc/self/fd/57 -> /dev/ion
file : false, /proc/self/fd/58 -> /dev/ion
file : false, /proc/self/fd/59 -> /dev/hwbinder
file : true, /proc/self/fd/63 -> /data/app/com.google.android.gms-xErOVYdgUuUxSUGYRGwZ0A==/split_config.en.apk
file : true, /proc/self/fd/64 -> /data/app/com.google.android.gms-xErOVYdgUuUxSUGYRGwZ0A==/split_config.xxhdpi.apk
在 Android 8.0+(API 级别 26)上,可以获得更多详细信息:
for (f in File("/proc/self/fd").listFiles())
try
Log.i(TAG, "file : $f.isFile, $f -> $java.nio.file.Files.readSymbolicLink(f.toPath())")
catch (ex: Exception)
Log.w(TAG, "Failed to get info for $f")
...
file : false, /proc/self/fd/50 -> /dev/kgsl-3d0
file : false, /proc/self/fd/51 -> socket:[3647176]
file : false, /proc/self/fd/52 -> socket:[3648033]
file : false, /proc/self/fd/53 -> anon_inode:[eventfd]
file : false, /proc/self/fd/54 -> socket:[3648028]
file : false, /proc/self/fd/55 -> socket:[3648030]
file : false, /proc/self/fd/56 -> anon_inode:[eventpoll]
file : false, /proc/self/fd/57 -> /dev/ion
file : false, /proc/self/fd/58 -> /dev/ion
file : false, /proc/self/fd/59 -> /dev/hwbinder
file : true, /proc/self/fd/63 -> /data/app/com.google.android.gms-xErOVYdgUuUxSUGYRGwZ0A==/split_config.en.apk
file : true, /proc/self/fd/64 -> /data/app/com.google.android.gms-xErOVYdgUuUxSUGYRGwZ0A==/split_config.xxhdpi.apk
【讨论】:
以上是关于Firebase DB:应用程序打开了太多文件。一个进程中可用文件描述符的最大值默认为 1024的主要内容,如果未能解决你的问题,请参考以下文章
应用程序可能在 Andriod 中的主线程(Firebase 数据库)上做了太多工作
Kafka Streams应用程序在kafka服务器上打开了太多文件
与 SqlDataAdapter.Fill() 相比,DataTable.Load() 花费了太多时间
带有 JdbcIO 编写器的 ApacheBeam/DataFlow 运行器创建了太多连接