Nonetheless we however sometimes bring crashes with OutOfMemory. So wheres the garbage enthusiast?
Im gonna target among the many cases where huge items in memory space cant become eliminated for a lengthy time frame. This example just isn’t in the end a memory problem objects is gathered at some time therefore we occasionally dismiss it. This isn’t advisable as it can sometimes lead to OOM problems.
Possible Im describing is the Handler problem, which can be often found as a caution by Lint.
Practical Instance

This really is a very basic task. Notice that this private Runnable has-been submitted towards Handler with a very long wait. Well run they and turn the device handful of days, after that dump storage and analyze it.
We now have seven tasks in memories now. This will be not really great. Lets know why GC struggles to clear them.
The query I designed to see a summary of all recreation leftover in memories is made in OQL (Object Query vocabulary), which can be simple, yet effective.
As you can plainly see, one of several strategies try referenced by this$0 . It is an indirect resource from private course into holder class. This$0 is referenced by callback , basically next referenced by a chain of further s of content back again to the key bond.
When you make a non-static course inside the owner class, Java produces an indirect regard to the proprietor
As soon as you publish Runnable or information into Handler , it’s subsequently stored in directory of information commands referenced from LooperThread till the message try accomplished. Posting postponed communications is a clear leak for at least committed associated with the wait price. Posting immediately produces a short-term drip at the same time in the event the waiting line of communications is actually huge.
Fixed Runnable Remedy
Lets attempt to overcome a memory space drip by getting eliminate this$0 , by transforming the unknown class to static.
Run, rotate acquire the memories dump.
What, once again? Lets see which keeps referring to Activities .
Take a good look at the bottom of the forest task was kept as a mention of mContext inside mTextView your DoneRunnable class. Utilizing static inner tuition is certainly not adequate to mastered memory space leakage, however. We need to would most.
Static Runnable With WeakReference

Lets keep using iterative repairs and obtain gone the reference to TextView, which keeps activity from getting damaged.
Remember that we have been keeping WeakReference to TextView, and lets operated, turn and dispose of storage.
Be careful with WeakReferences. They can be null at any moment, thus deal with all of them first to a regional variable (tough research) then examine to null before use.
Hooray! Only one task instance. This eliminates our memory space challenge.
Therefore with this strategy we must:
- Incorporate fixed inner sessions (or outer sessions)
- Incorporate WeakReference to any or all objects controlled from Handler / Runnable
In the event that you examine this code into original rule, you could find a big difference in readability and signal approval. The first signal is a lot shorter and much crisper, and youll notice that fundamentally, book in textView are going to be altered to Done. You should not see the code to realise that.
Writing anywhere near this much boilerplate signal is very tedious, particularly when postDelayed is scheduled to a short time, such 50ms. You will find better and crisper options.
Cleaning All Information onDestroy
Handler lessons provides an interesting feature removeCallbacksAndMessages – which could accept null as argument. It will probably remove all Runnables and Messages uploaded to some handler. Lets utilize it in onDestroy .
Lets operate, turn and dump memory space.
Good! One case.
This process is actually way better compared to earlier one, since it keeps signal clear and clear. The actual only real cost would be to make every effort to clean all information on task / fragment demolish.
We have one more option which, if youre idle like me, you could like even more. 🙂
Utilize WeakHandler
The Badoo teams came up with the fascinating thought of exposing WeakHandler – a course that behaves as Handler , but is means safer.
Required benefit of tough and weakened records to eradicate memories leaks. I will explain the concept in detail a bit after, but lets look at the signal first:
Much like the first code apart from one small variation instead of utilizing android.os.Handler , Ive used WeakHandler . Lets run, turn and dump memories:
Wonderful, is not they? The laws was cleaner than before, and mind is actually clean as well! 🙂
To make use of they, merely create dependency your build.gradle:
And import it inside java lessons:
Explore Badoos github page, where you could fork they, or examine it’s resource signal
WeakHandler. The way it works
The key aim of WeakHandler is to keep Runnables / emails hard-referenced while WeakHandler can hard-referenced. Once it can be GC-ed, all information should go aside aswell.
The following is straightforward drawing that displays differences when considering utilizing normal Handler and WeakHandler to share anonymous runnables:
Looking at the top drawing, Activity helps to keep a mention of Handler , which posts Runnable (throws it into queue of information referenced from bond). All things are okay except the indirect resource from Runnable to Activity . While information is in the waiting line, all graphs cant feel garbage-collected.
By comparison, during the base drawing Activity retains WeakHandler , which will keep Handler in. As soon as we ask they to publish Runnable , its wrapped into WeakRunnable and uploaded. So that the Message waiting line keeps research and then WeakRunnable . WeakRunnable helps to keep weakened mention of the specified Runnable , therefore, the Runnable could be garbage-collected.
Another small trick usually WeakHandler nonetheless helps to keep a tough reference to the specified Runnable , visit this website right here to avoid it from being garbage-collected while WeakRunnable is actually effective.
The side-effect of employing WeakHandler usually all communications and runnables may possibly not be executed if WeakHandler was garbage-collected. Avoiding that, just keep a reference to it from task. As soon as Activity is preparing to become obtained, all graphs with WeakHandler will obtained aswell.
Results
Utilizing postDelayed in Android requires additional effort. To quickly attain it we came up with three different ways:
- Make use of a static inner Runnable / Handler with WeakReference to owner class
- Sharp all messages from Handler in onDestroy of task / Fragment
- Incorporate WeakHandler from Badoo as a gold round
Its your responsibility to choose your selected method. The second looks affordable, but demands some extra services. The 3rd is actually my favourite, demonstrably, nevertheless need some interest as well WeakHandler should not be used without difficult resource from exterior. And thank you for reading!