AndroidOOM processing and image processing software

Source: Internet
Author: User

AndroidOOM processing and image processing software

Q: How can I optimize and cope with OOM problems in Android?

OOM may occur in the following situations:

1. large objects need to be loaded in the application, such as Bitmap.

Solution: When we need to display large bitmap objects or a large number of bitmaps, We need to compress them to prevent OOM problems. We can set BitmapFactory. the inJustDecodeBounds attribute of Optiions is true, so that the image will not be loaded into the memory, but the width and height attributes of the image will be read. We can use this attribute to compress bitmap.

In addition, the object pool can be used to reduce gc.

For Bitmap objects that are not used, we need to recycle them in time. Otherwise, Memory leak may occur. Therefore, when we determine that Bitmap objects are not used, we need to call Bitmap in time. recycle () method to make it GC as soon as possible

Do not use setImageBitmap, setImageResource, or BitmapFactory. decodeResource to set a large image. After decode is completed, these functions are implemented through the createBitmap on the java layer and consume more memory.

Therefore, use BitmapFactory first. the decodeStream method creates a bitmap and sets it as the source of ImageView. The biggest secret of decodeStream is that it directly calls JNI> nativeDecodeAsset () to complete decode, you no longer need to use the createBitmap on the java layer, thus saving the java Layer Space.



2. useless objects cannot be gc, resulting in Memory Leak. That is, Memory leakage. I know the following aspects about memory leakage.

Memory leak Caused by static variables

Memory leak Caused by unreasonable use of Context

Memory leak Caused by non-static internal classes

Memory leak implied by the callback of the Drawable object


3. We can define the size of the Android heap memory for the head size of the application on the device.

In Android, the upper limit is 16 MB by default, and you can adjust the upper limit according to the actual hardware configuration, the adjustment method is to set a system attribute in a configuration file loaded at system startup:

Dalvik. vm. heapsize = 24 m

For some Android projects, the main cause of performance bottleneck is the memory management mechanism of Android. Currently, mobile phone manufacturers are stingy with RAM and are very sensitive to the impact of RAM on the Performance of software fluency, in addition to optimizing the heap memory allocation of the Dalvik virtual machine, we can also forcibly define the memory size of our software. We use the Dalvik provided by dalvik. system. the following example uses the VMRuntime class to set the minimum heap memory:

Private final static int CWJ_HEAP_SIZE = 6*1024*1024;

VMRuntime. getRuntime (). setMinimumHeapSize (CWJ_HEAP_SIZE); // set the minimum heap memory size to 6 MB. Of course, for memory compression, manual GC interference can also be performed.


4. When switching the view screen (landscape screen), the Activity of the landscape screen or landscape screen will be re-created. We think that the previously created Activity will be recycled, but what is the truth? The Java mechanism won't give you the same feeling. Before we release the Activity, MyThread is not destroyed because the run function is not finished. Therefore, the Activity (Mytest) referenced by it is also destroyed, therefore, memory leakage is also caused.

Some people like to use AsyncTask provided by Android, but in fact AsyncTask is more serious. This memory leakage problem occurs only when the run function does not end, however, the internal implementation mechanism of AsyncTask is to use ThreadPoolExcutor. the life cycle of the Thread object generated by this class is uncertain and cannot be controlled by the application. Therefore, if AsyncTask is used as the internal class of the Activity, it is more prone to memory leakage.

The main ways to improve thread problems are:

L change the internal class of the thread to the static internal class.

L use weak references to save Context in the program.


5. referenced by the pointer in JNI

Some classes in the Framework often create an object in the Java layer, and create an object in the C ++ layer. Then, use JNI to make the two objects reference each other (Save the address of the other party ), the BinderProxy object is a typical example. In this case, the objects at the Java layer will not be released.

As the program runs more and more times, the leaked memory will eventually reach the upper limit set by heapsize. In this case, the VM will throw an OutOfMemoryError and the memory will overflow.


6. The Cursor object is not properly closed.

(1) In practice, the logic of the Code is usually much more complex than the above example, but the general principle is that it must be properly disabled after the use of Cursor.

(2) If your Cursor needs to be turned on and off in different life cycle methods of the Activity, you can generally do this:

Open in onCreate () and close in onDestroy;

Open in onStart () and close in onStop;

Enable onResume () and disable it in onPause;

Enable/disable the pair lifecycle method.

(3) If the program uses a CursorAdapter (such as Music), you can use its changeCursor (Cursor cursor) method to disable the old Cursor and use the new Cursor.

(4) In cursor. try... catch (when cursor is not empty), in fact, the job of close is to release resources, including the RemoteException exception caught when the ContentObserver is deregistered through the Binder cross-process, so you don't need to try... catch.

(5) about deactive and close, deactive is not the same as close. You can see their API comments. If deactive has a Cursor, it indicates that it will still be used (using the requery method ), this Cursor will release some resources, but it is not completely released; If you confirm that you no longer use this Cursor, you must close it.

(6) In addition to Cursor, we sometimes perform operations on Database objects. For example, to modify an attachVolume method in MediaProvider, every time attach is detected as an external volume, a new database is created instead of the previous one. Do not forget to close the old database object when removing it. <! -- 6th: whether to consider removing the Database -->

File descriptor Leakage

Of course, it may be very lucky that the result set of each query is very small, and there will be no memory overflow for thousands of queries. However, there is another limitation in the Android Linux kernel, that is, the file descriptor limit, by default, this limit is 1024.

The file descriptor itself is an integer used to indicate the files and sockets opened by each process. The first open file is 0, and the second is 1. Linux sets an upper limit for the number of files that can be opened by each process. You can run the "ulimit-n" command to view the limit. In addition, the operating system has a system-level restriction.

Each time you create a Cursor object, you will apply to the kernel to create a shared memory, which is provided to the application process in the form of a file. The application process will obtain the descriptor of this file, and map it to your own process space. If a large number of Cursor objects are not properly closed, it is conceivable that there will be a large number of file descriptors in the shared memory that cannot be closed, coupled with other file descriptors in the application process, it is easy to reach the upper limit of 1024. Once it is reached, the process will be suspended.


7. correctly register/deregister the listener object

Some XxxListener objects are often used, or XxxObserver and XxxReceiver objects, and then registered using the registerXxx method and unregisterXxx method. Its usage is also very simple, but there are still some problems from some actual development code:

(1) the call of the registerXxx and unregisterXxx methods is usually similar to the opening/closing of the Cursor method. In the life cycle of the Activity, the result can be:

In onCreate (), in onDestroy (), unregitster;

In onStart (), in onStop (), unregitster;

In onResume (), in onPause (), unregitster;

(2) Forget unregister

I have seen a piece of code before. I defined a PhoneStateListener object in the Activity and registered it to TelephonyManager:

TelephonyManager. listen (l, PhoneStateListener. LISTEN_SERVICE_STATE );

However, when the Activity exits, the listener is canceled, and the following method is not called:

TelephonyManager. listen (l, PhoneStateListener. LISTEN_NONE );

Because the callback member variable of PhoneStateListener is registered to TelephonyRegistry, TelephonyRegistry is a background service that will continue to run. Therefore, the callback object cannot be released without cancellation, and the PhoneStateListener object cannot be released, resulting in the Activity object being released.


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.