Pracuję nad grą społecznościową, której głównym natywnym kodem jest Android NDK. Gra posiada 3 główne pthreads NDK:Przesyłanie zadań do puli wątków daje RejectedExecutionException
- gra gwint
- nitki komunikacja serwer
- główny wątek renderowania (nazywany przez Renderer.onRender)
Poza tym, na Jawie po stronie, używamy AdWhirl, która spawnuje swój własny wątek poprzez własne ScheduledExecutorService
, ale zawarliśmy każde wywołanie "zaplanuj", "prześlij", "opublikuj", "uruchom" itp. z blokiem try-catch, aby złapać RejectedExecutionException
. Jednak wciąż na wszystkich nowych wersjach nadal występuje strasznie RejectedExecutionException
.
Śledzenie stosu w usłudze Android Market pozostawia niewiele więcej wskazówek, a nasz dział kontroli jakości również nie może dokładnie zidentyfikować problemu, ponieważ prawie nie występuje podczas testu (tylko użytkownicy zgłaszali awarię). Wpływa tylko niewielką część naszych użytkowników, ale nadal jest to ponad 7000 wypadków tygodniowo (niewielka część w porównaniu z dużą liczbą zainstalować bazowej)
java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1876)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:774)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at c.onProgressUpdate(Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4632)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
java.util.concurrent.RejectedExecutionException: pool=128/128, queue=10/10
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1961)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:794)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1315)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at c.onProgressUpdate(Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
at dalvik.system.NativeStart.main(Native Method)
java.util.concurrent.RejectedExecutionException
at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:1876)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:774)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1295)
at android.os.AsyncTask.execute(AsyncTask.java:394)
at c.onProgressUpdate(Unknown Source)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:432)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4627)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
at dalvik.system.NativeStart.main(Native Method)
widzę! Dzięki za wskazówkę, czy mimo to zwiększysz rozmiar lub czy jest jakiś limit? W naszym kodzie nie używamy tylu AsyncTask, ale używamy ScheduledExecutorService i innych executorów i określamy większy threadpool. Istnieje sporo tych executorów, czy istnieje jakiś twardy limit dla całkowitej liczby wątków na wszystkich executorach? Jeśli istnieje łączny limit liczby wątków dla całej aplikacji, będę musiał sprawdzić, czy ... w pewnym momencie nasze aplikacje działają z więcej niż 20 wątkami ... – Zennichimaro
Nie ma twardego ograniczenia, jak na Diane , ale najlepszą praktyką jest zachowanie się w latach 10. Możesz ustawić [maksymalny rozmiar puli] (http://developer.android.com/reference/java/util/concurrent/ThreadPoolExecutor.html#setMaximumPoolSize (int)) – Reno
Po przepisaniu aplikacji, aby używać mniejszych Runnable i AsyncTask , a teraz działa i nie zauważono już wyjątku RejectedExecutionException. Dzięki Reno i Diane! – Zennichimaro