当前位置: 首页 > 知识库问答 >
问题:

如何处理:java。util。同时发生的TimeoutException:android。操作系统。粘合剂过氧化物。finalize()在出现10秒错误后超时?

通寂离
2023-03-14

我们在GcWatcher中看到了许多TimeoutExceptions。定稿,装订。完成和PlainSocketImpl。完成。其中90%发生在Android 4.3上。我们从Critercism收到了来自现场用户的报告。

错误是“com.android.internal.BinderInternal$GcWatcher.finalize()在10秒后超时”

java.util.concurrent.TimeoutException: android.os.BinderProxy.finalize() timed out after 10 seconds
at android.os.BinderProxy.destroy(Native Method)
at android.os.BinderProxy.finalize(Binder.java:459)
at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:187)
at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:170)
at java.lang.Thread.run(Thread.java:841)

到目前为止,我们还没有在家里重现这个问题,也没有找到可能的原因。

知道是什么导致的吗?任何想法如何调试这一点,并找出应用程序的哪一部分导致这一点?任何能阐明这个问题的东西都有所帮助。

更多堆栈痕迹:

1   android.os.BinderProxy.destroy  
2   android.os.BinderProxy.finalize Binder.java, line 482
3   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
4   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
5   java.lang.Thread.run    Thread.java, line 841  

2个

1   java.lang.Object.wait   
2   java.lang.Object.wait   Object.java, line 401
3   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 102
4   java.lang.ref.ReferenceQueue.remove ReferenceQueue.java, line 73
5   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
6   java.lang.Thread.run

3个

1   java.util.HashMap.newKeyIterator    HashMap.java, line 907
2   java.util.HashMap$KeySet.iterator   HashMap.java, line 913
3   java.util.HashSet.iterator  HashSet.java, line 161
4   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 755
5   java.util.concurrent.ThreadPoolExecutor.interruptIdleWorkers    ThreadPoolExecutor.java, line 778
6   java.util.concurrent.ThreadPoolExecutor.shutdown    ThreadPoolExecutor.java, line 1357
7   java.util.concurrent.ThreadPoolExecutor.finalize    ThreadPoolExecutor.java, line 1443
8   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
9   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
10  java.lang.Thread.run

4.

1   com.android.internal.os.BinderInternal$GcWatcher.finalize   BinderInternal.java, line 47
2   java.lang.Daemons$FinalizerDaemon.doFinalize    Daemons.java, line 187
3   java.lang.Daemons$FinalizerDaemon.run   Daemons.java, line 170
4   java.lang.Thread.run

共有3个答案

陶飞鸿
2023-03-14

我找到了一些关于这个问题的幻灯片。

http://de.slideshare.net/DroidConTLV/android-crash-analysis-and-the-dalvik-garbage-collector-tools-and-tips

在这张幻灯片中,作者告诉我们,如果堆中有很多对象或大型对象,那么GC似乎有问题。本幻灯片还包括一个示例应用程序的参考和一个用于分析此问题的python脚本。

https://github.com/oba2cat3/GCTest

https://github.com/oba2cat3/logcat2memorygraph

此外,我在这边的评论#3中发现了一个提示:https://code.google.com/p/android/issues/detail?id=53418#c3

斜宁
2023-03-14

我们经常在应用程序中看到这种情况,使用Crashlytics。崩溃通常发生在平台代码的底层。小样本:

Android数据库游标窗口。finalize()在10秒后超时

java.util.regex.Matcher.finalize()10秒后超时

Android图样位图$BitmapFinalizer。finalize()在10秒后超时

组织。阿帕奇。http。impl。conn.SingleClientConnManager。finalize()在10秒后超时

JAVAutil。同时发生的线程池执行器。finalize()在10秒后超时

Android操作系统。粘合剂过氧化物。finalize()在10秒后超时

android.graphics.Path.finalize()10秒后超时

发生这种情况的设备绝大多数(但不完全)是三星制造的设备。这可能仅仅意味着我们的大多数用户都在使用三星设备;或者,这可能表明三星设备存在问题。我不太确定。

我想这并不能真正回答您的问题,但我只是想强调,这似乎很常见,并且不是针对您的应用程序的。

袁青青
2023-03-14

完全披露-我是TLV DroidCon中前面提到的演讲的作者。

我有机会在许多Android应用程序中研究这个问题,并与遇到它的其他开发人员讨论它——我们都得到了相同的一点:这个问题无法避免,只能最小化。

我仔细研究了Android垃圾收集器代码的默认实现,以便更好地理解抛出此异常的原因以及可能的原因。我甚至在实验中发现了一个可能的根本原因。

问题的根源在于设备“进入睡眠”一段时间——这意味着操作系统决定通过停止大多数用户登录进程一段时间、关闭屏幕、减少CPU周期等方式来降低电池消耗。这样做的方式是在Linux系统级别上,进程在运行中暂停。这可以在正常应用程序执行期间的任何时候发生,但会在本机系统调用时停止,因为上下文切换是在内核级别完成的。这就是Dalvik GC加入故事的地方。

Dalvik GC代码(在AOSP站点的Dalvik项目中实现)不是一段复杂的代码。我的DroidCon幻灯片介绍了它的基本工作方式。我没有介绍的是基本的GC循环——收集器有一个要完成(和销毁)的对象列表。底部的循环逻辑可以简化如下:

  1. 开始时间戳
  2. 删除要释放的对象列表中的对象,
  3. 释放对象-finalize()并调用本机destroy(),如果需要,
  4. 结束\u时间戳
  5. 计算(end\u timestamp-start\u timestamp)并与硬编码的10秒超时值进行比较,
  6. 如果超时已达到-抛出java。util。同时发生的TimeoutException并终止进程

应用程序在做它自己的事情。

这不是面向用户的应用程序,它在后台运行。

在此后台操作期间,将创建、使用对象,并需要收集对象以释放内存。

应用程序不需要WakeLock,因为这会对电池产生不利影响,而且似乎没有必要。

这意味着应用程序将不时调用GC。

一般来说,GC的运行是顺利完成的。

有时(极少数情况下)系统会决定在GC运行中间Hibernate。

如果您运行应用程序的时间足够长,并且密切监视Dalvik内存日志,就会发生这种情况。

现在考虑基本GC循环的时间戳逻辑-设备可以启动运行,取一个<代码> STARTHORKSTOR> <代码>,并在系统代码对象的<代码>销毁()/<代码>本地调用中睡觉。

当它醒来并继续运行时,destroy()将完成,下一个end\u标记将是destroy()调用睡眠时间所用的时间。

如果睡眠时间长(超过10秒),则java。util。同时发生的将引发TimeoutException

我在分析python脚本生成的图表中看到了这一点——针对Android系统应用程序,而不仅仅是我自己监控的应用程序。

收集足够的日志,你最终会看到它。

这个问题无法避免-如果你的应用程序在后台运行,你会遇到它。

你可以通过使用唤醒锁来缓解,并防止设备睡眠,但这完全是另一回事,一个新的头痛,也许还有另一个骗局中的另一次谈话。

您可以通过减少GC调用来最大限度地减少问题,从而降低场景发生的可能性(提示见幻灯片)。

我还没有机会阅读Dalvik 2(也称为ART)GC代码,该代码拥有新一代压缩功能,也没有在AndroidLollipop上进行任何实验。

2015年7月5日增补:

在查看此崩溃类型的崩溃报告聚合后,看起来Android操作系统5.0版(含ART的Lollipop)中的这些崩溃只占此崩溃类型的0.5%。这意味着ART GC更改降低了这些崩溃的频率。

添加6/1/2016:

看起来Android项目已经添加了很多关于GC如何在Dalvik 2.0中工作的信息。

您可以在这里阅读-调试ART垃圾收集。

它还讨论了一些获取应用程序GC行为信息的工具。

向应用程序进程发送SIGQUIT将导致ANR,并将应用程序状态转储到日志文件中进行分析。

 类似资料:
  • 我在Lollipop上收到了奇怪的撞车报告。我的应用程序基本上是一个浏览器,所以它大量使用WebView,但我不知道问题发生在那里。不管怎样,崩溃报告没有提供太多有用的信息,它基本上是我下面粘贴的内容: 有人见过这个吗?知道是什么引起的吗? 编辑:我应该提到的是,这种情况发生在我已经使用了大约10个月的应用程序上,它一直只针对4.0设备。该漏洞仅在5.0设备上报告,上面的stacktrace是Pl

  • 在我的android应用程序中,我使用带有sqlcipher库的Room进行加密/解密。我经常在Crashlysis中看到以下崩溃: java.util.concurrent.超时异常:net.sqlcipher.database.SQLiteCompiledSql.finalize()在sun.misc.Unsafe.park(本地方法)在java.util.concurrent.locks.L

  • 更新到appium版本1.20.0后,这个未知的服务器端错误开始更频繁地发生,我以前见过这个错误,但真的是零星的,我认为这是由于断开引起的超时,现在每次我在同一个版本中运行测试时都会发生执行点。 Appium版本:1.20.0设备:Pixel 3(仿真器)Android API 30 鸦片原木 亚洲开发银行日志

  • 在Eclipse(luna)安装中,我很难让Glassfish服务器真正启动并保持运行。 我有Glassfish在Netbean工作正常。 我已经在Eclipse中创建了服务器,我可以启动它,但是进度条到达大约69%,然后停止,最终给我一个错误: 无法按时启动服务器。JAVAutil。同时发生的超时异常 奇怪的是,当我等待错误出现时,我可以转到localhost:8080,服务器正在运行,我也可以

  • 问题内容: 好吧,这是我在下面进行的操作,以获取错误,但不知道为什么数据库连接失败。 创建一个新的ASP.NET网站 将新的* .mdf数据库添加到App_Data 使用Visual Studio中的服务器资源管理器向其中添加一些表 右键单击“数据库”,然后单击“复制连接”字符串。如下所示将其插入WebConfig文件 问题答案: 我有一个偷偷摸摸的怀疑,它与权限有关。完全控制您的“授权用户”。

  • 我们公司的应用程序遇到了崩溃,但这个问题不一定存在,我现在无法重现这个问题,我们可以为我提供下一个解决方案的想法 id.finalize()id是RandomAccessFile的子类。 此堆栈跟踪是: