What is the Android Message Pool?-source code analysis, androidpool
In Android, the Android Message mechanism is usually used for communication between threads, and this mechanism is used for Message transmission.
Generally, we use Message. obtain () and Handler. obtainMessage () to obtain the Message from the Message Pool, so as to avoid directly constructing the Message.
- So Will Android cause OOM because of the Message object cached by the Message Pool?For this problem, I can make it clear that the APP will not cause OOM due to the Message Pool. As for why, you can take a step-by-step look at the last section-how to store the Message Pool.
Message Obtain analysis Message. obtain () source code
/** * Return a new Message instance from 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(); }
From the code, we can see that the Message is directly assigned by sPool.
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. */ public final Message obtainMessage() { return Message.obtain(this); }
Handler. obtain () is finally obtained by calling Message. obtain.
Message Pool source code analysis Message Pool Data Structure
// sometimes we store linked lists of these things /*package*/ Message next; private static final Object sPoolSync = new Object(); private static Message sPool; private static int sPoolSize = 0; private static final int MAX_POOL_SIZE = 50; private static boolean gCheckRecycle = true;
The Code clearly shows that the data structure of the Message Pool is actually a linked list. SPool is a global message pool. sPoolSize records the length of the linked list. MAX_POOL_SIZE indicates that the maximum length of the linked list is 50.
How to store messages in the Message Pool
/** @hide */ public static void updateCheckRecycle(int targetSdkVersion) { if (targetSdkVersion < Build.VERSION_CODES.LOLLIPOP) { gCheckRecycle = false; } } /** * Return a Message instance to the global pool. * <p> * You MUST NOT touch the Message after calling this function because it has * effectively been freed. It is an error to recycle a message that is currently * enqueued or that is in the process of being delivered to a Handler. * </p> */ public void recycle() { if (isInUse()) { if (gCheckRecycle) { throw new IllegalStateException("This message cannot be recycled because it " + "is still in use."); } return; } recycleUnchecked(); } /** * Recycles a Message that may be in-use. * Used internally by the MessageQueue and Looper when disposing of queued Messages. */ void recycleUnchecked() { // Mark the message as in use while 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++; } } }
From the code analysis perspective, the core method of message pool storage is the above recycleUnchecked () method:
1. Leave the field of the Message object to be recycled blank (to avoid static Message pool Memory leakage due to too much Message ).Therefore, no matter how large the original Message object is, the cached Message objects are left blank before being cached in the Message Pool. Therefore, the memory size of these cached Message objects can be ignored for an app memory.Therefore, the Message Pool does not cause the OOM of the App.
2. Use a built-in lock (thread security) to determine whether the current thread pool is smaller than 50. If the value is less than 50, insert the Mesaage directly to the end of the Message pool linked list. If the value is greater than or equal to 50, the discarded messages will be discarded by GC.
Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.