6 reasons for Android memory leaks

6 reasons for Android memory leaks

[[179035]]

1. Memory leak caused by resource object not being closed

describe:

Resource objects such as (Cursor, File, etc.) often use some buffers. When we are not using them, we should close them in time so that their buffers can reclaim memory in time. Their buffers exist not only in the Java virtual machine, but also outside the Java virtual machine. If we just set its reference to null without closing them, it will often cause memory leaks. Because some resource objects, such as SQLiteCursor (in the destructor finalize(), if we do not close it, it will call close() to close it by itself), if we do not close it, the system will also close it when it recycles it, but this efficiency is too low. Therefore, when a resource object is not in use, its close() function should be called to close it, and then set to null. Be sure to make sure that our resource objects are closed when our program exits.

Database queries are often performed in programs, but the Cursor is often not closed after use. If our query result set is relatively small, memory consumption is not easy to detect, and memory problems will only occur when a large number of operations are performed over a long period of time, which will bring difficulties and risks to future testing and troubleshooting.

Sample code:

  1. Cursor   cursor = getContentResolver().query(uri...);
  2.  
  3. if ( cursor .moveToNext()) {
  4.  
  5. ... ...
  6.  
  7. }

Corrected example code:

  1. Cursor   cursor = null ;
  2.  
  3. try {
  4.  
  5. cursor = getContentResolver().query(uri...);
  6.  
  7. if ( cursor != null && cursor .moveToNext()) {
  8.  
  9. ... ...
  10.  
  11. }
  12.  
  13. finally
  14.  
  15. if ( cursor != null ) {
  16.  
  17. try {
  18.  
  19. cursor.close ( ) ;
  20.  
  21. } catch (Exception e) {
  22.  
  23. // ignore this
  24.  
  25. }
  26.  
  27. }
  28.  
  29. }

2. When constructing the Adapter, the cached convertView is not used

describe:

Taking the construction of ListView's BaseAdapter as an example, the method is provided in BaseAdapter:

public View getView(int position, ViewconvertView, ViewGroup parent)

To provide ListView with the view objects required for each item. Initially, ListView will instantiate a certain number of view objects from BaseAdapter according to the current screen layout, and ListView will cache these view objects. When the ListView is scrolled up, the view object of the original top list item will be recycled and then used to construct the newly appeared bottom list item. This construction process is completed by the getView() method. The second parameter View convertView of getView() is the cached view object of the list item (if there is no view object in the cache during initialization, convertView is null). From this, we can see that if we do not use convertView, but re-instantiate a View object in getView() every time, it will waste resources and time, and will also cause more and more memory usage. The process of ListView recycling the view object of the list item can be viewed:

android.widget.AbsListView.java –> voidaddScrapView(View scrap) method.

Sample code:

  1. public   View getView( int position, ViewconvertView, ViewGroup parent) {
  2.  
  3. View   view = new Xxx(...);
  4.  
  5. ... ...
  6.  
  7. return   view ;
  8.  
  9. }

Corrected example code:

  1. public   View getView( int position, ViewconvertView, ViewGroup parent) {
  2.  
  3. View   view = null ;
  4.  
  5. if (convertView != null ) {
  6.  
  7. view = convertView;
  8.  
  9. populate( view , getItem(position));
  10.  
  11. ...
  12.  
  13. } else {
  14.  
  15. view = new Xxx(...);
  16.  
  17. ...
  18.  
  19. }
  20.  
  21. return   view ;
  22.  
  23. }

3. Call recycle() to release memory when the Bitmap object is not in use

describe:

Sometimes we will manually operate Bitmap objects. If a Bitmap object takes up a lot of memory, when it is no longer in use, you can call the Bitmap.recycle() method to recycle the memory occupied by the pixels of this object, but this is not necessary and depends on the situation. You can take a look at the comments in the code:

  1. /**
  2.  
  3. Free up the memory associated with thisbitmap's pixels, and mark the
  4.  
  5. • bitmap as   "dead" , meaning it will throw an exception if getPixels() or   
  6.  
  7. •setPixels() is called, and will drawothing. This operation cannot be
  8.  
  9. •reversed, so it should only be called ifyou are sure there are no   
  10.  
  11. •further uses for the bitmap. This is anadvanced call, and normally need
  12.  
  13. not be called, since the normal GCprocess will free up this memory when   
  14.  
  15. •there are no more references   to this bitmap.
  16.  
  17. */

4. Try to use the context of the application instead of the context of the activity

This is a very subtle case of memory leak. There is a simple way to avoid context related memory leaks. The most obvious one is to avoid context escaping from its scope. Use Application context. The life cycle of this context is the same as the life cycle of your application, not the life cycle of the activity. If you want to keep a long-lived object, and this object needs a context, remember to use the application object. You can get it by calling Context.getApplicationContext() or Activity.getApplication(). For more information, please see this article on how to avoid

5. Memory leak caused by registration not being cancelled

Some Android programs may reference objects of our Anroid program (such as registration mechanism). Even if our Android program has ended, other referencing programs still have references to certain objects of our Android program, and the leaked memory still cannot be garbage collected. UnregisterReceiver is not called after registerReceiver is called.

For example, if we want to listen to the phone service in the system to obtain some information (such as signal strength, etc.) in the lock screen interface (LockScreen), we can define a PhoneStateListener object in LockScreen and register it with the TelephonyManager service. For the LockScreen object, a LockScreen object will be created when the lock screen interface needs to be displayed, and the LockScreen object will be released when the lock screen interface disappears.

However, if we forget to cancel the PhoneStateListener object we registered before when releasing the LockScreen object, the LockScreen object cannot be garbage collected. If the lock screen interface is constantly displayed and disappeared, it will eventually cause OutOfMemory due to the large number of LockScreen objects that cannot be recycled, causing the system_process process to hang.

Although some system programs seem to be able to automatically cancel registration (of course not in time), we should still cancel registration explicitly in our program, and all registrations should be canceled when the program ends.

6. Memory leak caused by not cleaning up objects in the collection

We usually add some object references to the collection, and when we don't need the object, we don't clear its reference from the collection, so the collection will become larger and larger. If the collection is static, the situation is even more serious.

<<:  Butterknife full analysis

>>:  How to make your product stand out in the Apple App Store in 2017?

Recommend

How long is the life of a smartphone? It can be long or short.

With the development of technology, smartphones h...

Is the FBI no match for Facebook?

I saw a foreign media report that the facial recog...

How to build and operate the core capabilities of membership products?

We must be familiar with membership products, but...

iOS implements the production of complex interfaces with multiple variable cells

In daily development, we sometimes encounter inte...

Group buying ends: How does Hongtu Sanbao “blend” Lashou?

After a long wait, the second shoe finally droppe...

How much does it cost to be an agent for a fruit mini program in Xingtai?

What is the price of being an agent of Xingtai Fr...

Millennium Populus euphratica, is it really 1,000 years old?

Your browser does not support the video tag It is...