最近有一些OOM的错误上报
java.lang.OutOfMemoryError: Could not allocate JNI Env
极少量的
java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Out of memory
一个典型的用户状态是这样的
用户使用时长 1小时56分11秒 前后台状态 后台
设备机型 OPPO R9S 系统版本 Android 6.0.1,level 23
可用内存大小 1.97 GB ( 56.21% ) 可用存储空间 32.91 GB ( 61.23% )
整理异常信息发现各版本机型均有发生,于是去asop查看了错误信息,以及搜索了一下类似堆栈
一个地方是堆操作时
系统源码文件:/art/runtime/gc/http://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";
另一个个地方是创建线程时
系统源码文件:/art/runtime/http://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)));
线程限制检查有很多考量因素,不同系统设置不太一样,具体可以见参考链接内容
解决方式
问题原因就是创建了过多的线程,这个过程一般是因为线程创建时逻辑问题,或者线程执行过程中阻塞了造成不能及时释放导致的
我们要先定位到问题线程,编程过程中强制给所有线程命名,包括线程池,OkHttp的Dispatcher等常见场景
如果是第三方一般支持线程信息分析,自己也可以在Thread.UncaughtExceptionHandler获取到对应错误时,收集线程现场
排查过程中也可以使用ps命令来对一些场景进行校验 ps -elfT 来查看线程使用情况,使用=组合 wc -l可以计算数量。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)