1. java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: FATAL EXCEPTION: main
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: Process: com.sec.android.app.camera, PID: 13806
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at java.lang.Thread.nativeCreate(Native Method)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at java.lang.Thread.start(Thread.java:883)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at java.lang.Runtime.exit(Runtime.java:157)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at java.lang.System.exit(System.java:1494)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.morphoinc.util.VideoRec.VideoRecorder$CodecInputSurface.checkEglError(VideoRecorder.java:656)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.morphoinc.util.VideoRec.VideoRecorder$CodecInputSurface.makeCurrent(VideoRecorder.java:627)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.morphoinc.util.VideoRec.VideoRecorder.end(VideoRecorder.java:528)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.morphoinc.rapideffect.obj.EffectRenderer.stopVideoRecording(EffectRenderer.java:442)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.morphoinc.rapideffect.obj.EffectImage.stopVideoRecording(EffectImage.java:160)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.android.camera.VideoModule.stopMorphoColorEffectRecording(VideoModule.java:4768)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.android.camera.VideoModule.onVideoButtonClick(VideoModule.java:4891)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.android.camera.VideoUI$26.onClick(VideoUI.java:1362)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at android.view.View.performClick(View.java:7869)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.android.camera.ui.FloatingImageView.performClick(FloatingImageView.java:335)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at com.android.camera.FloatingShutterButton.performClick(FloatingShutterButton.java:123)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at android.view.View.performClickInternal(View.java:7838)
09-09 02:00:19.416 10109 13806 13806 E AndroidRuntime: at android.view.View.access$3600(View.java:886)
2. terminating with uncaught exception of type std::__1::system_error: thread constructor failed: Try again'
pid: 31634, tid: 17258, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
uid: 10110
signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr --------
Abort message: 'terminating with uncaught exception of type std::__1::system_error: thread constructor failed: Try again'
r0 00000000 r1 0000436a r2 00000006 r3 0154eb50
r4 0154eb64 r5 0154eb48 r6 00007b92 r7 0000016b
r8 0154eb60 r9 0154eb50 r10 0154eb80 r11 0154eb70
ip 0000436a sp 0154eb20 lr f332d2c3 pc f332d2d6
backtrace:
#00 pc 0005f2d6 /apex/com.android.runtime/lib/bionic/libc.so (abort+166) (BuildId: d84af0b640b3e9d365f37fe8072558b3)
#01 pc 0003606b /system/lib/libc++.so (abort_message+86) (BuildId: 5f821e82f14869be6a5954103be40403)
#02 pc 000361eb /system/lib/libc++.so (demangling_terminate_handler()+178) (BuildId: 5f821e82f14869be6a5954103be40403)
#03 pc 00044eb7 /system/lib/libc++.so (std::__terminate(void (*)())+2) (BuildId: 5f821e82f14869be6a5954103be40403)
#04 pc 00044711 /system/lib/libc++.so (__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*)+12) (BuildId: 5f821e82f14869be6a5954103be40403)
#05 pc 0004467d /system/lib/libc++.so (__cxa_throw+72) (BuildId: 5f821e82f14869be6a5954103be40403)
#06 pc 0007fb5d /system/lib/libc++.so (std::__1::__throw_system_error(int, char const*)+84) (BuildId: 5f821e82f14869be6a5954103be40403)
#07 pc 00022b2b /system/lib/libsfplugin_ccodec.so (android::CCodec::initiateRelease(bool)+374) (BuildId: a2ad64c1e3f303266081ca63ae1a5173)
#08 pc 000b0267 /system/lib/libstagefright.so (android::MediaCodec::onMessageReceived(android::sp<android::AMessage> const&)+4462) (BuildId: cddf6dc228aa8070bf6ab635211be723)
#09 pc 00012f6d /system/lib/libstagefright_foundation.so (android::AHandler::deliverMessage(android::sp<android::AMessage> const&)+24) (BuildId: 6690acfb13302e609df5a26a580815e4)
#10 pc 0001534d /system/lib/libstagefright_foundation.so (android::AMessage::deliver()+64) (BuildId: 6690acfb13302e609df5a26a58081
查看tomestone 文件
tombstone_00
Line 6: pid: 31634, tid: 17258, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 16208, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17264, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17272, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17285, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17293, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17304, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17331, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17355, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17382, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17406, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17422, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17429, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17432, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17439, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17442, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
pid: 31634, tid: 17449, name: MediaCodec_loop >>> com.sec.android.app.camera <<<
.....很多
oom的错误地方
1.第一个地方是堆操作时
系统源码文件:
/art/runtime/gc/heap.cc 函数:
void Heap::ThrowOutOfMemoryError(Thread* self, size_t byte_count, AllocatorType allocator_type) 抛出时的错误信息:
oss << “Failed to allocate a ” << byte_count << ” byte allocation with ” << total_bytes_free << ” free bytes and ” <<
PrettySize(GetFreeMemoryUntilOOME()) << ” until OOM“;
Java堆OOM
这种抛出的其实就是堆内存不够用的时候,即前面提到的申请堆内存大小超过了Runtime.getRuntime().maxMemory()
2.第二个地方是创建线程时
系统源码文件:
/art/runtime/thread.cc 函数:
void Thread::CreateNativeThread(JNIEnv* env, jobject java_peer, size_t stack_size, bool is_daemon) 抛出时的错误信息:
“Could not allocate JNI Env”
或者
StringPrintf(“pthread_create (%s stack) failed: %s”,
PrettySize(stack_size).c_str(), strerror(pthread_create_result)));
看了一下,大概的意思基本都是线程的问题
异常信息有1040KB stack,这个表示当前系统线程栈的大小,与系统设置有关,每个机器可能不相同。 Android系统通常不会限制线程数,栈内存是限制。
通过ulimit -s 或者ulimit -a查看
对问题点进行复现分析,操作步骤:
1. 查看进程id
ps -A | grep camera
2. 根据进程ID,操作应用可以实时查看 fd(句柄), threads
当线程数(可以在/proc/pid/status中的threads项实时查看)超过/proc/sys/kernel/threads-max中规定的上限时产生OOM崩溃
ls proc/pid/fd | wc -l //查看 句柄
cat proc/pid/status //查看当前进程的所有状态
cat proc/pid/status | grep Threads //查看当前进程的 总线程数
ps -A -T | grep 28823 | wc -l // (wc -l 是用来统计数量的)
//可以利用 linux 的 inotify 机制进行监控:
//watch /proc/pid/fd | wc -l 来监控 app 打开文件的情况,
//watch cat proc/pid/status | grep Threads 来监控线程使用情况.
3. 查看当前app 所有的线程
cd /proc/pid/fd
ps -A -T | grep 28823
u0_a53 12497 12497 459 3104936 299612 SyS_epoll_wait 0 S roid.app.camera
u0_a53 12497 12503 459 3104936 299612 futex_wait_queue_me 0 S Jit thread pool
u0_a53 12497 12508 459 3104936 299612 do_sigtimedwait 0 S Signal Catcher
u0_a53 12497 12509 459 3104936 299612 poll_schedule_timeout 0 S ADB-JDWP Connec
u0_a53 12497 12510 459 3104936 299612 futex_wait_queue_me 0 S HeapTaskDaemon
u0_a53 12497 12511 459 3104936 299612 futex_wait_queue_me 0 S ReferenceQueueD
u0_a53 12497 12512 459 3104936 299612 futex_wait_queue_me 0 S FinalizerDaemon
u0_a53 12497 12514 459 3104936 299612 binder_ioctl_write_read 0 S Binder:12497_1
u0_a53 12497 12515 459 3104936 299612 binder_ioctl_write_read 0 S Binder:12497_2
u0_a53 12497 12516 459 3104936 299612 binder_ioctl_write_read 0 S Binder:12497_3
u0_a53 12497 12517 459 3104936 299612 futex_wait_queue_me 0 S Profile Saver
u0_a53 12497 12519 459 3104936 299612 SyS_epoll_wait 0 S CameraHolder
u0_a53 12497 12520 459 3104936 299612 binder_ioctl_write_read 0 S Binder:12497_4
u0_a53 12497 12531 459 3104936 299612 futex_wait_queue_me 0 S WorksThread
u0_a53 12497 12532 459 3104936 299612 futex_wait_queue_me 0 S WorksThread
u0_a53 12497 12669 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12670 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12671 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12672 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12970 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12971 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12972 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12973 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12974 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12975 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12976 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 12977 459 3104936 299612 futex_wait_queue_me 0 S roid.app.camera
............................//很多 很多 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 20404 459 3104936 299876 futex_wait_queue_me 0 S roid.app.camera
u0_a53 12497 20537 459 3104936 299876 futex_wait_queue_me 0 S Timer-149
u0_a53 12497 20538 459 3104936 299876 futex_wait_queue_me 0 S SoundPool
u0_a53 12497 20539 459 3104936 299876 futex_wait_queue_me 0 S SoundPoolThread
u0_a53 12497 20560 459 3104936 299876 futex_wait_queue_me 0 S pool-26-thread-
u0_a53 12497 20565 459 3104936 299876 futex_wait_queue_me 0 S SoundPool
u0_a53 12497 20566 459 3104936 299876 futex_wait_queue_me 0 S SoundPoolThread
u0_a53 12497 20567 459 3104936 299876 SyS_epoll_wait 0 S CameraBackgroun
u0_a53 12497 20568 459 3104936 299876 SyS_epoll_wait 0 S CameraImageAvai
u0_a53 12497 20569 459 3104936 299876 SyS_epoll_wait 0 S CameraCaptureCa
u0_a53 12497 20570 459 3104936 299876 SyS_epoll_wait 0 S MpoSaveHandler
u0_a53 12497 20571 459 3104936 299876 SyS_epoll_wait 0 S PreviewHandlerT
u0_a53 12497 20725 459 3104936 299876 SyS_epoll_wait 0 S ScrollHandlerTh
u0_a53 12497 20735 459 3104936 299876 futex_wait_queue_me 0 S Timer-150
u0_a53 12497 20741 459 3104936 299876 futex_wait_queue_me 0 S Timer-151
u0_a53 12497 20743 459 3104936 299876 futex_wait_queue_me 0 S Timer-152
u0_a53 12497 20753 459 3104936 299876 futex_wait_queue_me 0 S Timer-153
u0_a53 12497 20930 459 3104936 299876 futex_wait_queue_me 0 S AsyncTask #23
u0_a53 12497 21294 459 3104936 299876 futex_wait_queue_me 0 S AudioTrack
u0_a53 12497 21297 459 3104936 299876 futex_wait_queue_me 0 S MediaCodec_loop
u0_a53 12497 21298 459 3104936 299876 futex_wait_queue_me 0 S CodecLooper
u0_a53 12497 21305 459 3104936 299876 futex_wait_queue_me 0 S MediaCodec_loop
看看当前app是哪些线程占用较多,且一直增长无回落, 有名称的在后面显示, 无名称的是app的名称
排查:排查是哪个线程一直在增长, 可以用watch (可以利用 linux 的 inotify 机制进行监控:)
如果总数在不断地操作,创建thread 必然导致最后线程数的增长最后导致OOM。
对线程池优化,
1. ExecutorService 可能会导致 oom 变换成 ThreadPoolExecutor
2. 对mediaCodec 的释放, 放在 finally 中, 确保必定停止