(conveniently leave GitHub link, need to get relevant interview content can go to find) github.com/xiangjiana/…

In the development of Android applications, in order to prevent memory overflow, soft reference and weak reference technology can be applied as far as possible when dealing with some objects that occupy large memory and have a long declaration period.

Soft/weak references can be used in conjunction with a ReferenceQueue (ReferenceQueue), and if the object referenced by the soft reference is collected by the garbage collector, the Java virtual machine adds the soft reference to the ReferenceQueue associated with it. Using this queue, you can get a list of objects with soft/weak references that have been reclaimed, thus clearing invalid soft/weak references for the buffer.

Let’s say our app uses a lot of default images, like a default avatar, a default game icon, etc., and these images are used in a lot of places. If you try to read the picture every time, because the reading of the file requires hardware operation, the speed is slow, resulting in low performance. So we thought about caching the images and reading them directly from memory when needed. However, because images occupy a large memory space, caching many images requires a large amount of memory, which may be prone to OutOfMemory exceptions. At this point, we can consider using soft/weak citation techniques to avoid this problem.

Here’s a prototype of a high-speed buffer: First define a HashMap that holds soft reference objects.

  private Map <String, SoftReference<Bitmap>> imageCache = new Has 
  hMap <String, SoftReference<Bitmap>> ();
Copy the code

Define a method that holds a soft reference to a Bitmap into a HashMap.





If you are more concerned about the usability of your application and want to reclaim some memory-heavy objects as quickly as possible, you can use weak references.

You can also choose soft or weak references based on how often the object is used. If the object is likely to be used frequently, use soft references. If it is more likely that the object will not be used, use weak references

Ok, back to the subject. As mentioned earlier, creating a static Handler inner class and then using a weak reference to the object held by the Handler can also reclaim the object held by the Handler when it is recycled, but this avoids Activity leakage. However, the MessageQueue of the Looper thread may have messages waiting to be processed, so we should remove messages from the MessageQueue MessageQueue when we Destroy or Stop the Activity.

There are several ways to remove a Message:

  public final void removeCallbacks(Runnable r); 
  public final void removeCallbacks(Runnable r, Object token); 
  public final void removeCallbacksAndMessages(Object token); 
  public final void removeMessages(int what); 
  public final void removeMessages(int what, Object object);
Copy the code
  • If a member variable is declared static, we all know that its lifetime is the same as the entire app process lifetime.

    This can lead to a number of problems. If your app processes are designed to stay in memory, that memory will not be released even if your app cuts to the background. According to the current mobile app memory management mechanism, background processes that occupy a large amount of memory will be recycled preferentially, because if the APP performs process mutual insurance, it will cause the app to restart frequently in the background. After the installation of the APP you participated in the development of the phone, the phone will be drained of power and traffic overnight, and your APP has to be uninstalled or silent by users. The fix here is:

Do not initialize static members at class initialization. Consider lazy initialization. The architectural design should consider whether it is really necessary to do this and avoid it as much as possible. If the architecture needs to be designed this way, then it is your responsibility to manage the life cycle of this object.

  • avoidoverride finalize()

    1. The execution time of finalize method is uncertain, so we cannot rely on finalize method to release scarce resources. The reasons for the uncertainty are:
  • The time for the VIRTUAL machine to invoke GC is uncertain
  • Finalize Daemon threads are scheduled at an uncertain time

Finalize method will be executed only once. Even if objects are resurrected, finalize method will not be executed when OBJECTS are GC again. The reasons are as follows: Object with Finalize method is a Finalize reference generated by the virtual machine when new, and when Finalize method is executed, The Finalize Reference corresponding to the object will be released, even if the object is resurrected at this time (that is, the object is referenced by strong Reference). When THE Finalize method is GC for the second time, the Finalize method will not be executed because there is no Finalize Reference.

3. Objects with Finalize methods can be released only after at least two rounds of GC.

  • Memory leak caused by resource not being closed

    For using theBraodcastReceiver.ContentObserverThe Cursor, File, Stream, Bitmap, and other resources should be closed or deregistedwhen the Activity is destroyed. Otherwise, these resources will not be reclaimed, resulting in memory leaks.
  • Some code does not leak memory, but either does not release unused memory efficiently and promptly, or does not use existing objects efficiently and requests new memory frequently.

For example, when the Adapter is constructed, instead of using a cached convertView, a new convertView is created each time. The ViewHolder is recommended.

Conclusion:

  • References to components such as an Activity should be controlled within the Activity’s lifecycle; If not, consider using itgetApplicationContextorgetApplicationTo prevent the Activity from being leaked by references to objects in the external lifecycle.
  • Try not to use non-static external member variables (including context) in static variables or static inner classes, and if you do, consider emptying external member variables when appropriate. You can also use weak references in an inner class to refer to variables of an outer class.
  • For inner class objects with a lifetime longer than the Activity, and the inner class uses the member variables of the outer class, you can avoid memory leaks by:
    • Change the inner class to static inner class
    • Weak references are used in static inner classes to refer to a member variable of an outer class
  • It is best to use weak references for reference objects that are held by the Handler. When resources are released, messages in the Handler can also be emptied. For example, inActivity onStoporonDestroy“, cancel theHandlerThe object’sMessageandRunnable.
  • The best way to do this is to explicitly assign an object to null when you’re not using it, such as calling Recycle () after using Bitmap. Set to null to clear arrays that have direct or indirect references to resources such as images (array.clear(); Array = null), it is best to follow the principle of who creates who releases.
  • Close resources correctly for use byBraodcastReceiver.ContentObserverUse of Cursor, File, Stream, Bitmap, etc. should be closed or deregister when the Activity is destroyed.
  • Be sensitive to the life cycles of objects, paying special attention to the life cycles of singletons, static objects, global collections, and so on.

Deleted a part, forgive me _ (easily left GitHub link, need to get relevant interview content can go to find) github.com/xiangjiana/…