又是抓脑壳的一天!Thread线程也会OOM?

本文探讨了Android线程过度使用可能导致的OOM问题,特别是在华为手机上的严格限制。作者通过实验发现,超过一定数量的线程会导致应用崩溃。文章分析了线程数的增长原因,如第三方框架的使用,并提供了使用Android Profiler检查线程数量的方法。解决方案包括调整RxJava和Kotlin协程的线程池设置,以及使用Transform在编译时替换线程池构造。此外,作者建议通过lint限制直接new线程的行为,以防止线程OOM。
摘要由CSDN通过智能技术生成

本文首发掘金:Thread也会OOM吗?
作者:究极逮虾户

OOM其实是一个比较常见的异常了,但是不知道各位老哥有没有见过这个异常。

java.lang.OutOfMemoryError: pthread_create (1040KB stack) failed: Try again
	at java.lang.Thread.nativeCreate(Thread.java)
	at java.lang.Thread.start(Thread.java:1076)
	at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1338)
...

由于国内手机厂商的奇奇怪怪的优化,特别是华为,其对于线程的构建有特别严苛的要求,当进程内总线程数量达到一定的量级的情况下就会发生线程OOM问题。

这个问题其实有人专门做过分析,我这个人还是不喜欢直接复制别人的文章,但是读书人嘛,借书怎么能叫偷呢。不可思议的OOM

在Android7.0及以上的华为手机(EmotionUI_5.0及以上)的手机产生OOM,这些手机的线程数限制都很小(应该是华为rom特意修改的limits),每个进程只允许最大同时开500个线程,因此很容易复现了。

  for (i in 0 until 3000) {
            Thread {
                while (true) {
                    Thread.sleep(1000)
                }
            }.start()
        }

这个是作者做的一个实验,当华为手机的线程创建超过500的时候就会发生崩溃的问题了。但是我自己写了个demo,发现也不是所有的华为手机都这样,我用NOVA7测试出来的结果大概是3000个线程才会出现崩溃的问题。

线上真的会有超过500个线程的情况出现吗?

如何查看当前线程数量?

Android Profiler 工具非常强大,里面就有当前进程启动的线程数量,以及其cpu调度情况的。

图上可以看出来THREADS 后面的就是当前的线程使用数量。一个只含有少量代码的安卓项目执行的时候其实也有大概30条左右的线程存在,而OKHttp,Glide,第三方框架,Socket以及启动任务栈等等第三方框架接入后,线程数量更是会出现一个井喷式增长。

线上问题原因分析?

我观察了下我们的项目的线程使用情况,发现当项目完成简单的初始化之后就会构建出大概300条左右的线程,其实还是比较感人的。而线上的使用情况很复杂,而且报错日志上的错误并不是oom的真实原因,而是压死骆驼的最后一根稻草。

我其实在上家公司的时候就发生过这个问题,当时我们跟踪源代码,发现在使用rxjava的Schedulers.io()导致的这个问题。

  static final class CachedWorkerPool implements Runnable {
        private final long ke
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值