Android OutOfMemoryErrors似乎没有立即终止活动 - 为什么?

时间:2011-01-20 09:09:48

标签: android exception-handling out-of-memory

我正在通过使用Thread.setDefaultUncaughtExceptionHandler回调运行的代码从客户端收集崩溃日志。

在我没有附加设备ID与我的上传之前,但现在我,我看到一些非常奇怪的报告。基本上,在1-2分钟的时间内,我看到同一客户端上传的50个左右OutOfMemoryError崩溃日志,有时在同一秒内报告两个或更多日志。

我假设由具有setDefaultUncaughtExceptionHandler的父线程生成的线程也在使用处理程序,因此一旦第一个OutOfMemoryError发生,级联效果就会立即触及所有应用程序线程。也许这些线程中的许多都可以在整个应用程序关闭之前上传崩溃日志。但是,我原以为这个例外会导致应用程序更快地终止。

这是一个具体的例子 - 我看到这个堆栈在45秒的范围内大约10次,有时在同一秒内重复,我本来期望第一个这样的异常完全取下应用程序,而不是拖出来:

java.lang.RuntimeException: An error occured while executing doInBackground()
    at android.os.AsyncTask$3.done(AsyncTask.java:200)
    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
    at java.lang.Thread.run(Thread.java:1096)
Caused by: java.lang.OutOfMemoryError
    at java.lang.AbstractStringBuilder.(AbstractStringBuilder.java:83)
    at java.lang.StringBuilder.(StringBuilder.java:68)
    at com.appspot.myapp.util.RestClient.convertStreamToString(RestClient.java:306)
    at com.appspot.myapp.util.RestClient.executeRequest(RestClient.java:288)
    at com.appspot.myapp.util.RestClient.Execute(RestClient.java:185)
    at com.appspot.myapp.GridViewActivity$LoadProfilesTask.doInBackground(GridViewActivity.java:1135)
    at com.appspot.myapp.GridViewActivity$LoadProfilesTask.doInBackground(GridViewActivity.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:185)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

有人可以解释当Android遇到OutOfMemoryError时会发生什么以及为什么我会看到这种行为?这就好像应用程序继续跛行并将这些错误视为非致命......?

谢谢!

2 个答案:

答案 0 :(得分:0)

您是否正在替换默认的未捕获异常处理程序?

如果是这样,您的替换是否会调用停止VM的内容(例如System.exit())?未捕获的异常不会自动导致整个VM停止。

答案 1 :(得分:0)

法登,

在我的代码中,我在这里存储了默认的异常处理程序:

this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();

然后,在我完成将异常信息上传到我的服务器之后,我调用了默认的异常处理程序:

defaultUEH.uncaughtException(t, e);

在上面链接到的代码中给出这些行:

  84             } finally {
  85                 // Try everything to make sure this process goes away.
  86                 Process.killProcess(Process.myPid());
  87                 System.exit(10);
  88             }

我仍然对我的代码如何在OutOfMemoryErrors面前继续运行感到困惑。