当前位置:网站首页>Record the handling of oom problems caused by too many threads at one time

Record the handling of oom problems caused by too many threads at one time

2022-06-26 10:15:00 Shake half a bottle of vinegar

Recently, I encountered a problem caused by too many threads OOM problem , Record and share here , Avoid the same problem next time .

cause

Recently, the testers have been checking APP Test in weak network environment , The result appeared many times during the test crash,crash The stack information of is shown in the figure below .

From the information in the figure, we can see , Is due to OOM As a result of crash, And OOM The reason is that there are too many threads .

The first problem location

Considering that this problem occurs in the process of weak network environment testing , The first reaction that comes to mind is , These threads are roughly the threads of network requests , Because of the weak network , Network requests are slow , Threads are occupied and stacked , More and more , In the end, it led to OOM Appearance .

Based on this idea , I'll start with the code in the network request section , We APP The network framework used is retrofit+rxjava, among ,rxjava The version is rxjava2. Basically, all network request codes in the project , The method of switching to the sub thread for network requests is to use subscribeOn(Schedulers.io()) To achieve , At first glance, there is no problem ,Schedulers.io() Is for IO Operation design thread pool , And the network request is really IO Operation Oriented , But when we look carefully Schedulers.io() The definition of , We can find that this is supported by an unbounded thread pool Scheduler, It applies to non CPU Dense I/O Work , Such as accessing the file system 、 Perform a network call 、 Access to databases and so on . This Scheduler There is no limit , Its thread pool can be on demand Growing all the time . Focus here ,Schedulers.io() It's kind of like java In the thread pool newCachedThreadPool, If there are no reusable threads , The system keeps creating new threads , Finally, too many threads are generated OOM problem .

Solution

Since the cause of the problem is that the network request is in Schedulers.io() On the implementation , There is no limit to the number of threads created , Cause too many threads , Then I will change a thread pool to implement thread management of network requests, which can solve the problem . here , We noticed that rxjava One way is Schedulers.from(Executor executor), Make the task execute in the customized thread pool , So in the single instance of the network request management class , Use newFixedThreadPool Create a fixed-size thread pool , All network requests are executed in this thread pool .

later , In the process of searching for relevant information on the Internet , I have also seen that others have the same problems and github On the RxAndroid Mentioned issue,JakeWharton Responded to this , The reason is the same as what we analyzed before , meanwhile , He proposed another solution , Use RxJava2CallAdapterFactory Of createAsync Method to construct Retrofit example , This creates a completely asynchronous Observeable, There is no need to throw it into your own designated thread scheduler , It only needs observeOn The main thread is OK . But such a change ,subscribeOn Method pair createAsync Finally constructed Observeable It doesn't matter , in other words , As long as you use createAsync, Even if it is called later subscribeOn It will not affect the threads of network requests , Until you call observeOn Before ( Include map Wait for the operation ), Threads will not switch .

The second problem location

After the repair of scheme 1 ,OOM The problem has been improved , But it's not completely solved OOM problem , therefore , Started the second problem positioning . At the second positioning , Use android studio Self contained profiler The tool analyzes cpu Operation of the , See which threads are invading resources , It turns out that when the number of online trips keeps rising , A large number of threads appear in the thread list OkHttp ConnectionPool The thread of , Normally ,OkHttpBuilder Creating OkHttp Client When , Only one thread with the number of... Should be created 5, The survival time is 5 Minutes of thread pool , Now there are a lot of OkHttp ConnectionPool The thread of must be OkHttp Client There was a problem creating the .

Solution

Finally found , There are a series of requests in the project because baseUrl It is obtained from the platform interface , So for this series of developments baseUrl The interface of , The developer creates a new one each time OkHttp Client, Finally, it leads to more threads , Last OOM. To reduce code changes , The solution finally uses a pair of OkHttp Client Set up a common thread pool to serve as a thread pool when creating connectionPool, Don't create it again .

Have a chat

Now there are many materials for online learning , They are also copying each other . Look at all the information on the Internet retrofit+rxjava Framework , Introduction and other articles , It's all about teaching developers to use web requests Schedulers.io() To switch to sub thread execution , Took everyone into the pit , Actually, take a close look at rxjava How many to him Scheduler Description of , You can avoid this problem , So for the same introductory articles on the Internet , Keep a cautious attitude when reading .

 

原网站

版权声明
本文为[Shake half a bottle of vinegar]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202170546557721.html