如何调试:RealmError - 打开太多文件

时间:2017-02-03 02:05:23

标签: android realm

我使用Realm构建应用程序已经有一段时间了,不过我一直在讨论这个问题。

我目前正在使用Realm插件:io.realm:realm-gradle-plugin:2.3.0

例外是:

Fatal Exception: java.lang.Error: io.realm.exceptions.RealmError: Unrecoverable error. Too many open files in /home/cc/repo/realm/realm-java-release/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 92
    at io.realm.AndroidNotifier.throwBackgroundException(AndroidNotifier.java:138)
    at io.realm.internal.async.QueryUpdateTask.run(QueryUpdateTask.java:128)
    at io.realm.internal.async.BgPriorityRunnable.run(BgPriorityRunnable.java:34)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)
Caused by io.realm.exceptions.RealmError: Unrecoverable error. Too many open files in /home/cc/repo/realm/realm-java-release/realm/realm-library/src/main/cpp/io_realm_internal_SharedRealm.cpp line 92
    at io.realm.internal.SharedRealm.nativeGetSharedRealm(SharedRealm.java)
    at io.realm.internal.SharedRealm.getInstance(SharedRealm.java:209)
    at io.realm.internal.SharedRealm.getInstance(SharedRealm.java:186)
    at io.realm.internal.async.QueryUpdateTask.run(QueryUpdateTask.java:80)
    at io.realm.internal.async.BgPriorityRunnable.run(BgPriorityRunnable.java:34)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:423)
    at java.util.concurrent.FutureTask.run(FutureTask.java:237)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
    at java.lang.Thread.run(Thread.java:818)

我(在应用运行时)查询了打开文件的数量adb shell ls -l /proc//fd

运行时,我看到文件userxxx.management/access_control.new_commit.cv已打开182次,userxxx.lock已打开91次。

任何提示或指示将不胜感激! 干杯, 加文

2 个答案:

答案 0 :(得分:1)

您需要检查打开close领域实例的位置。 this question描述了同样的问题 Christian Melchior先生在评论中解释了这个错误的原因:

  

打开太多文件表示您在某种程度上打开了太多Realms,因为系统已经用完了文件描述符。这也可以解释内存问题。由于Realm正在缓存Realms pr。线程这可能发生在不同的线程上,也可能是因为您创建了许多不同的域。 - Christian Melchior 12月15日和16日在10:11

答案 1 :(得分:0)

所以我想出这个的方法是使用Android设备监视器和一个小shell脚本:

#!/bin/bash
my_watch () {
    tput sc
    pid=$1; while [ true ]; do
        tput rc; tput el
        printf "$2" `adb shell ls -l /proc/${pid}/fd | wc -l`
        sleep .1
    done
    tput rc; tput ed;
}

clear

APP_NAME=${1:?missing application name}

pid=`adb shell ps | grep $1 | awk '{print $2}'`

echo "Watch number of files in use for App: $1 PID: $pid - Ctrl-C to stop"
my_watch $pid "Files in use %s"

(在watch_usage.sh中保存以上内容并在终端窗口中使用./watch_usage.sh com.application.example执行,这将尝试告诉您当前应用程序正在使用的文件数。)

当应用程序运行时,我注意到跳过的文件数量,然后我使用ADM的DDMS透视图来查看当前的Thread列表。有(在我的情况下)我的RealmTransactionQueue的一些线程(这应该是一个单独的(现在是)但是当我第一次创建它时,我引入了一个小错误,意味着它一次又一次地获得新版本) ...我可以通过查看DDMS窗口中的每个线程并查看它们的起始位置来看到这一点。

谢谢@sergey,你的预感是正确的,这是由于失控线程!

希望以上帮助某人(如果不是我下次的话!)。

GAV株系