This helps united states with many different low-level problems such as memory administration, program means dependencies, etc.

However we nevertheless occasionally get collisions with OutOfMemory. So wheres the garbage enthusiast?

Im planning concentrate on one of many cases where huge things in memory space cant getting eliminated for a long time period. This case just isn’t ultimately a memory leak objects are gathered at some time so we occasionally dismiss it. That isn’t better as it can certainly sometimes create OOM problems.

The fact Im describing is the Handler drip, that is frequently found as a warning by Lint.

Important Example

who is carmella dating

This is a very standard task. Observe that this unknown Runnable has been uploaded toward Handler with a very long wait. Well work it and rotate the telephone number of instances, subsequently dispose of memory and assess it.

We seven tasks in storage today. This is certainly not at all close. Lets know precisely why GC struggles to clear them.

The query I designed to bring a list of all Activities leftover in memory space was made in OQL (item Query Language), which will be quite simple, yet powerful.

Clearly, among the many activities are referenced by this$0 . This is exactly an indirect research from anonymous class with the manager lessons. This$0 is actually referenced by callback , basically then referenced by a chain of then s of information back into an important bond.

Any time you generate a non-static lessons in the proprietor lessons, Java brings an indirect mention of the master

As soon as you publish Runnable or information into Handler , it is then kept in listing of content commands referenced from LooperThread up until the content is executed. Uploading delayed messages is an obvious drip for at least the amount of time associated with wait price. Sharing straight away causes a short-term leak aswell in the event the waiting line of messages are large.

Fixed Runnable Answer

Lets make an effort to get over a memories problem through getting gone this$0 , by converting the anonymous class to static.

Operate, rotate to get the mind dump.

Exactly what, once again? Lets read who keeps talking about Activities .

Take a good look at the base of the tree task was stored as a mention of mContext inside mTextView of your DoneRunnable lessons. Utilizing fixed interior sessions just isn’t sufficient to conquer storage leakages, nonetheless. We must perform even more.

Static Runnable With WeakReference

sapphire dating

Lets keep using iterative solutions acquire eliminate the mention of the TextView, which keeps activity from getting destroyed.

Observe that we’re maintaining WeakReference to TextView, and lets work, turn and dump mind.

Be careful with WeakReferences. They may be null at any moment, so resolve all of them initial to a local variable (hard research) and then see to null before need.

Hooray! Only 1 activity case. This resolves our memories issue.

Very for this strategy we have to:

  • Incorporate fixed interior tuition (or outside tuition)
  • Use WeakReference to any or all things controlled from Handler / Runnable

In the event that you contrast this signal on initial signal, you will probably find a huge difference in readability and signal approval. The first laws is a lot smaller and far better, and youll see that fundamentally, book in textView would be altered to Done. No need to see the signal to realise that.

Creating this much boilerplate code is extremely tedious, particularly if postDelayed is scheduled to a short amino app while, eg 50ms. Discover best and crisper possibilities.

Cleanup All Communications onDestroy

Handler class has an appealing feature removeCallbacksAndMessages – that may recognize null as argument. It is going to remove all Runnables and communications published to a specific handler. Lets utilize it in onDestroy .

Lets operate, turn and dispose of memories.

Good! Just one case.

This approach is way better than the previous one, since it keeps rule obvious and readable. The sole expense will be don’t forget to remove all information on activity / fragment kill.

I have another answer which, if youre sluggish anything like me, you could including even more. 🙂

Incorporate WeakHandler

The Badoo employees came up with the interesting thought of exposing WeakHandler – a class that acts as Handler , but is means reliable.

Required advantageous asset of tough and weakened sources relieve storage leaks. I will explain the theory thoroughly a bit later on, but lets go through the laws first:

Nearly the same as the first code aside from one tiny huge difference in the place of using android.os.Handler , Ive made use of WeakHandler . Lets operate, rotate and dispose of memory space:

Cool, isnt they? The code are cleaner than in the past, and memory space try thoroughly clean at the same time! 🙂

To utilize they, simply include addiction to your build.gradle:

And transfer they in your coffee class:

Visit Badoos github web page, where you are able to fork it, or study its resource rule

WeakHandler. How it functions

The primary goal of WeakHandler is always to hold Runnables / information hard-referenced while WeakHandler can also be hard-referenced. As soon as it could be GC-ed, all information is going out also.

Listed here is a simple diagram that displays differences when considering utilizing normal Handler and WeakHandler to post private runnables:

Looking at the top drawing, Activity helps to keep a mention of the Handler , which content Runnable (throws it into waiting line of emails referenced from Thread). Things are fine except the secondary resource from Runnable to Activity . While content is in the queue, all graphs cant be garbage-collected.

In contrast, inside bottom diagram Activity holds WeakHandler , which will keep Handler around. Whenever we query they to publish Runnable , it’s wrapped into WeakRunnable and published. And so the Message queue helps to keep reference merely to WeakRunnable . WeakRunnable keeps weak mention of the the required Runnable , therefore, the Runnable tends to be garbage-collected.

Another small secret would be that WeakHandler nevertheless helps to keep a hard mention of the required Runnable , avoiding it from are garbage-collected while WeakRunnable try productive.

The side-effect of utilizing WeakHandler is the fact that all messages and runnables may possibly not be executed if WeakHandler was garbage-collected. Avoiding that, just keep a reference to they from task. When task is ready to be gathered, all graphs with WeakHandler will collected at the same time.

Results

Using postDelayed in Android requires additional work. To reach they we created three different ways:

  • Need a fixed inner Runnable / Handler with WeakReference to owner class
  • Sharp all messages from Handler in onDestroy of task / Fragment
  • Utilize WeakHandler from Badoo as a silver bullet

it is for you to decide to choose your selected method. The next looks very reasonable, but needs a little extra perform. The third was my personal preferred, clearly, however it need some attention also WeakHandler really should not be used without hard reference from external. And thank you so much for checking!