Introduction
In Android, we usually use Android's messaging mechanism to communicate between threads, and this mechanism passes exactly the message.
Usually. We use Message.obtain () and Handler.obtainmessage () to get a message from the message pool. Avoid constructing a message directly.
- So does Android cause oom because of the message pool cache message object?
For this question, I can understand that app*** will not be oom*** by the message pool. As for why, can take a step-by-step look down, impatient can directly see the last section--message pool how to store a Message.
Obtain analysis
Handler.obtainmessage () Source code
/** * Returns a new {@link android.os.Message Message} from the global message pool. More efficient than * creating and allocating new instances. The retrieved message has its handler set to this instance (Message.target == this). * If you don‘t want that facility, just call Message.obtain() instead. */ publicfinalobtainMessage() { return Message.obtain(this); }
Obviously. Handler.obtain () is called Message.obtain () to obtain. Then we'll look at the Message.obtain. () Source code
/** * Return a new Message instance F Rom the global pool. Allows us to * avoid allocating new objects in many cases. */ public static Message obtain () {synchronized (spoolsync) {if (sPool! = null ) {Message m = sPool; SPool = M.next; M.next = null ; M.flags = 0 ; //clear In-use flag spoolsize--; return m; }} return new Message (); }
The above code gives us a few key information:
1. Learn a bit of data structure. From the above code slice basically can determine that spool is a linked list structure. The other spool itself is a message.
2. If the list spool is not empty, then the obtain () method takes a message object from the spool header of the list and assigns it to M, returning as the return value. Otherwise. A message object that is directly new.
the spool here is actually the message Pool.
Message Pool related source code Analysis message Pool data structure
Public Final class Message implements parcelable { //Sometimes we store linked lists of these things /*package*/Message Next;Private Static FinalObject Spoolsync =NewObject ();Private StaticMessage SPool;Private Static intSpoolsize =0;Private Static Final intMax_pool_size = -;}
Did you see the key information? The members of the message have next, spool, and spoolsize. This is a little bit of a data structure, very quickly can be judged that this is a typical list of the implementation of the structure. Spool is a global message pool that is a linked list. Next records the next element in the linked list, spoolsize records the linked list length. Max_pool_size indicates that the maximum length of a linked list is 50.
Message pool how to store message
Public Final class Message implements parcelable { Private Static BooleanGcheckrecycle =true;/** @hide * / Public Static void updatecheckrecycle(intTargetsdkversion) {if(Targetsdkversion < Build.version_codes. LOLLIPOP) {gcheckrecycle =false; } }/** * Return A Message instance to the global pool. * <p> * You must don't touch the Message after calling this function because it has * effectively been freed. It is an error to recycle a message which is currently * enqueued or that's in the process of being delivered to a Ha Ndler. * </p> * * Public void Recycle() {if(Isinuse ()) {if(gcheckrecycle) {Throw NewIllegalStateException ("This message cannot is recycled because it"+"is still on use."); }return; } recycleunchecked (); }/** * Recycles a Message that is May in-use. * Used internally by the MessageQueue and Looper when disposing of queued Messages. */ voidRecycleunchecked () {//Mark the message as in and the It remains in the recycled object pool. //Clear out all other details.Flags = Flag_in_use; what =0; Arg1 =0; Arg2 =0; obj =NULL; ReplyTo =NULL; Sendinguid =-1; when =0; target =NULL; callback =NULL; data =NULL;synchronized(Spoolsync) {if(Spoolsize < Max_pool_size) {next = SPool; SPool = This; spoolsize++; } } }}
Look at the code analysis. The core method of storing a message pool is the recycleunchecked () method above:
- Empty the Message object field to be reclaimed (avoid the message being too large. Causes a static message pool memory leak). so no matter how big the original Message object is. The memory size of the cached message object is basically negligible for an app memory when it is finally cached in the message pool before being emptied. so say. The Message pool does not cause the app to Oom.
- Determines whether the current thread pool size is less than 50, in the form of a built-in lock (thread-safe). If it is less than 50, insert the mesaage directly into the end of the message pool list, if greater than or equal to 50. is discarded directly. Then these discarded message will be processed by GC.
Summarize
What is the message pool of Android, the message pool will cause oom--source code Angle Analysis