For a long time, Android developed, found that Android application development is easy to start, but advanced or become a senior engineer, the need to have the basic ability is very high: performance optimization, memory leakage, apk slimming, heat repair and so on, these are very test a person's ability. Android has a long way to go, and it's going to keep going. This article mainly introduces the knowledge of the Android memory leak. In fact, to really understand the memory leak, need to have a certain understanding of the JVM, the Java language, on this basis it is easier to understand this article.
A. Memory leak concept
In Java, if an object has no available value, but is pointed to by another reference, the object is not a garbage for GC, so it is not recycled, but we think it should be garbage and should be recycled by GC. This object does not get GC recovery, it will always live in the heap memory, occupy memory, as we say bully the truth is not poop. This leads to a leak of memory.
Why is a memory leak, the root cause is an object that will never be used, because some references are not disconnected, do not meet the GC conditions, resulting in not being recycled, which caused a memory leak. For example, a broadcast receiver is registered in an activity, but a memory overflow occurs when the page is unregister when it is closed. If our Java has been running for a long time, and this memory leak continues to occur, then there is no memory available, and ultimately we see the oom error. While the Android memory leak is an application-level leak (every application in Android is run independently in a separate process, each application process has a memory cap specified by the virtual machine, and a oom error occurs when the memory footprint exceeds that value). The process is forced to kill, and the kill process memory is reclaimed by the system, but for a development engineer, no memory leaks can be spared.
Two. Where memory leaks occur and solutions
Handler intermittent post messages in 1.activity, causing activity leaks
1.1 Appearing occasions:
{
Handler Mleakyhandler = Handler () {
(message msg) {
}
}
(Bundle savedinstancestate) {
. OnCreate (savedinstancestate);
Mleakyhandler.postdelayed (Runnable () {
() {}}
, * *);
}
}
1.2 Causal Analysis:
When the activity is finished, the delayed message continues to survive for 10 minutes in the main thread's message queue until they are processed. The message holds the handler reference to the activity, which implicitly holds his external class (in this case, sampleactivity). The reference will not be released until the message is processed. The activity is therefore not recycled by the garbage collection mechanism, revealing the application resources he holds. Note that the anonymous Runnable class on line 15th is the same. A non-static instance of an anonymous class holds an implicit external class reference, so the context will be compromised.
Specific order of reference:
Messagequeue->message->runnable->handler->activity. So this causes the current activity to be associated with MessageQueue, causing the Leakactivity object not to be reclaimed by GC, resulting in a memory leak.
1.3 Solution:
To solve this problem, handler subclasses should be defined in a new file or use a static inner class. Static inner classes do not implicitly hold references to external classes. So it will not cause its activity to leak. If you need to invoke the method of external activity within handle, let handler hold a weak reference to the activity (weakreference) so that you don't accidentally cause the context to leak. To resolve the memory leaks that might result from our instantiation of the anonymous runnable class, we will use a static variable to refer to him (because static instances of anonymous classes do not implicitly hold references to their external classes).
{
Runnable srunnable = Runnable () {
() {
}
};
MyHandler Mhandler = MyHandler ();
(Bundle savedinstancestate) {
. onCreate (savedinstancestate);
Mhandler.postdelayed (srunnable, * *);
Finish ();
}
{
weakreference<sampleactivity> mactivity;
(sampleactivity activity) {
mactivity = weakreference<sampleactivity> (activity);
}
(msg) {
sampleactivity activity = Mactivity.get ();
(Activity!=) {
}
}
}
}