Ошибки Android OutOfMemory не появляются, чтобы немедленно прекратить деятельность - почему? - PullRequest
0 голосов
/ 20 января 2011

Я собираю журналы сбоев от клиентов с помощью кода, который запускается с обратным вызовом Thread.setDefaultUncaughtExceptionHandler.

Раньше я не прикреплял идентификатор устройства в своих загрузках, но теперь я получаю очень странные отчеты. По сути, в течение 1-2 минут я вижу примерно 50 OutOfMemoryError журналов аварий, все загруженные одним и тем же клиентом, иногда с двумя или более журналами, сообщаемыми в одну и ту же секунду.

Я предполагаю, что потоки, порожденные родительским потоком с setDefaultUncaughtExceptionHandler, также используют обработчик, поэтому после первого OutOfMemoryError происходит каскадный эффект, который затрагивает все потоки приложения одновременно. Возможно, многие из этих потоков могут загрузить журнал сбоев до того, как все приложение выйдет из строя. Однако я ожидал, что это исключение приведет к более быстрому завершению работы приложения.

Вот конкретный пример - я вижу этот стек ~ 10 раз в течение 45 секунд, а иногда несколько раз в течение одной секунды, и я ожидал бы, что первое такое исключение полностью закроет приложение, а не перетянет его:

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 голосов
/ 24 января 2011

Fadden,

В моем коде я храню обработчик исключений по умолчанию здесь:

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.

0 голосов
/ 21 января 2011

Заменяете ли вы обработчик необработанных исключений по умолчанию?

Если это так, вызывает ли ваша замена что-то, что останавливает ВМ (например, System.exit ())?Неопределенные исключения автоматически не приводят к остановке всей виртуальной машины.

...