Android Performance Optimization-avoid Memory leakage
I used to read similar translations on the Internet, but I forgot about them. until recently, I saw the original article again on the official website. Although it was a long time ago, I still thought it was a good conclusion. so I decided to translate and consolidate my knowledge.
Original article link
Android applications in most models (for older models, the current mobile phone configuration is getting higher and higher, and the allocable running memory will also increase accordingly) will get 16 MB of application memory. even if you do not plan to use all the memory, you should try to use less memory to avoid the process being killed by the system because the memory usage is too large. more apps are retained in the memory of the Android mobile phone (for a short time), so the user will get a response faster when switching between these reserved apps ). during work, memory leakage occurs, and most of the cases are caused by references that take a long time (objects, resources, and so on) in the Context of the application.
In Android, a Context is used in many operations, but most of them are used to load and use resources. This is why all components (Widgets) need to receive a Context parameter in the constructor. in general Android applications, you usually have two kinds of Context, Activity and Applicatin. this usually means that the developer first needs to pass the Context to the class and method:
@Overrideprotected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad"); setContentView(label);}
This means that Views have a reference in the entire Activity, and therefore the Activity will (tightly) Keep these Views: Usually the parent View and child View at all levels of the View, and the resources used by these views. therefore, if you disclose the Context (leak ). (Here, "leakage" means that you have kept a reference to avoid being recycled by the GC-garbage collection mechanism), and will gradually leak a lot of memory. if you do not pay attention to it, it is easy to leak the memory of the entire Activity.
When the screen is switched, the system will destroy the current Activity by default and save the Activity according to the status before the previous Activity is destroyed (the developer must manually Save the status before destruction) create a new Activity. in this way, Android will reload the UI layout and resources of the application. now you don't want to apply a large bitmap in every direction (portrait or landscape ). so the simplest way to keep this bitmap is not to reload it every time you invert the screen, it is to set it to static ):
private static Drawable sBackground;@Overrideprotected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad"); if (sBackground == null) { sBackground = getDrawable(R.drawable.large_bitmap); } label.setBackgroundDrawable(sBackground); setContentView(label);}
This code block runs very quickly, but it is also very incorrect; it will lead to memory leakage of the first Activity created during screen inversion. when a Drawable is used in a View, a Drawable callback is set for the View. in the code block above, this means that drawable has an application in TextView, and this TextView itself has another reference in the Activity (context. similarly, the Activity maintains the reference of various resources (of course, depending on your code ).
This is one of the simplest examples of leaking Context memory. Here you can findUnbindDrawables () method
) See how it works. when the Activity is destroyed, the drawable stored in (referenced) is called back to null. interestingly, in some cases where you have created a chain for mutual reference between resources, this is not good, but it makes the application consume memory faster.
There are two simple methods to avoid the leakage of contextual memory. one of the most significant ways is to prevent resources from being out of their context (and exists ). the above example shows the case of static reference. The internal class and the reference contained in this class may be the same danger to other classes. the second solution is applicableApplication
This context object. the Application will always exist when the Application is running and will not be affected by its lifecycle like the Activity. if you want to keep a long-term object, you need a Context ). you can easily call Context. getApplicationContext () and Activity. getApplication () method to obtain it.
To avoid Memory leakage, remember the following:
- Do not keep reference for a long time in the Activity (the reference should be the same as the Activity life cycle, the Activity is destroyed, and the reference is left empty)
- (For some references that require long-term persistence) Try to use Application instead of Activity
- If you cannot control the lifecycle of a class, avoid using non-static internal classes in the Activity. it is best to use static internal classes and weak references in the Activity. the solution to these problems is that an internal class used by an external class should use WeakReference for weak reference (for related examples, see ViewRoot)
- The garbage collection mechanism of the system does not guarantee that the memory will not be leaked.