Tuesday, September 21, 2010

Message Object Pooling in Android

The Message object pool in Android is implemented as an unbounded singly linked list. We will illustrate the pooling process with the creation and reclamation of two Message objects.
Initially, there is no Message object in the system. The mPool object, which is the head of the linked list, references to nothing (i.e. is null):

Now, we make the following two calls:
Message m1 = Message.obtain();
Message m2 = Message.obtain();
Since the linked-list pointed to by mPool is empty, Android will create two disjoint Message objects.  There is no linkage between them and the head.
Now, we send these two messages to a handler:
Handler h = new Handler() {
   @Override
   public final void handleMessage(final Message message) {
      // Do nothing.
   }
};
m1.setTarget(h);
m2.setTarget(h);
h.sendMessage(m1);
h.sendMessage(m2);
The Looper in the handler h will dispatch the two messages in the order of m1 and m2.  The dispatch sequence also determines the message reclamation sequence.  The Looper will call Message.recycle() on m1 and m2 after Handler.handleMessage() completes.  Each recycled Message object will be inserted to the head of the list.  So after m1.recycle() is called, the linked list becomes:
Note that the list now has just one element m1m2 is still dangling somewhere in the memory.  Android will call m2.recycle() after m2 is handled.  This inserts m2 into the head of the linked list:
Note that m2 and m1 will not be garbaged collected because mPool is a static reference.  If the linked list is not empty, a call to Message.obtain() will remove the head of the list and return that Message object to the caller.  In other words, no new object is created as long as the linked list has at least one unused Message object.  This design exhibits Locality of Reference.  The mostly recently used Message object is also re-used first.

No comments:

Post a Comment