Out of memory error in Android-Part 1

Source: Internet
Author: User


In the previous article, we didn't talk about it in too much detail. Here we will talk about it in detail:



 



1. What is outofmemoryerror:



Official reference:Thrown when a request for memory is made that can not be satisfied using the available platform resources. Such a request may be made by both the running application or by an internal function of the VM.
In layman's terms: it is an error thrown when the current available resources are not enough to request a piece of memory. We know that every androidProgramIt is an independent Dalvik VM instance. Each instance limits the maximum memory usage. If this limit is exceeded, the system will throw this error. Therefore, it does not have much to do with the remaining memory of the entire device. Of course, if the remaining memory of the device is insufficient to run another program, the system will select kill some programs to ensure that there is enough memory to run other programs.



 



2. Android memory composition:



The android memory is composed of two parts: Dalvik and native. Dalvik is the Java heap. The created object is allocated here, while native is the memory applied through C/C ++, bitmap is allocated in one way (after android3.0, the system allocates it through Dalvik by default ). Of course, no matter how it is allocated, the two parts cannot exceed the memory limit of Android on a single program.



 



3. Memory limit size:


 



1Activitymanager =(Activitymanager) Context. getsystemservice (context. activity_service );2Activitymanager. getmemoryclass ();


The above method will return numbers in MB, which may be different on different platforms or devices. For example, HTC G7 defaults to 24 m, Galaxy 36 m, emulator-2.3 24 m, etc.



 



4. actual usage of the program:



Take a simple Android program as an example. This program is the simplest Android project automatically generated using eclipse ADT. It has only one activity and the res directory automatically generated by the ADT. The test environment is as follows: emulator-2.3.3
Start the program and run the following command:



 


 



ADB shell dumpsys meminfo com. mem. Demo


 



Execution result:



 


Applications memory usage (KB) : Uptime: 1195344 realtime: 1195344** Meminfo in PID 333 [COM. Mem . Demo] ** native Dalvik other total -------------------------------------------------------- | size: 3968 5379 N/A 9347 | Allocated: 3964 2649 N/A 6613 | ---------------------------------------------------------- Free: 3 2730 N/A 2733 (PSS): 553 449 2516 3518 (shared dirty): 2272 1868 6648 10788 420 (priv dirty): 1140 32 1592Objects views: 0 viewroots: 0 Appcontexts: 0 activities: 0 Assets: 2 assetmanagers: 2 Local binders: 5 proxy binders: 10 Death recipients: 0 OpenSSL sockets: 0 SQL heap: 0 memory_used: 0 Pagecache_overflow: 0 malloc_size: 0 Asset allocations ZIP: /Data/APP/COM. Mem .Demo-1.apk:/resources. ARSC: 1 K


 



As shown in the figure above, the most simple Android program occupies about 6 MB of memory after startup (the above is 6613kb ). In addition to the android resources and classes, what else does the 6 M memory have:



To put it simply, some items will be preloaded during initialization, including classes and system resources, that is, some system la S, images, and so on. After Android is started, this part is shared to other programs through Memory sharing, so that other programs can call this part of resources,CodeCan refer to: http://goo.gl/EKvCV,android the entire starting process can refer to: http://goo.gl/K36Lr.



 



5. OOM:



To make Oom, We have rewritten the simplest program above:


Package COM. mem. demo; import android. app. activity; import android. graphics. bitmap; import android. graphics. bitmapfactory; import android. OS. bundle; public class demoactivity extends activity {bitmap map1, MAP2, map3, map4;/** called when the activity is first created. * // @ override public void oncreate (bundle savedinstancestate) {super. oncreate (savedinstancestate); setcontentview (R. layout. main); map1 = bitmapfactory. decoderesource (getresources (), R. drawable. big1); MAP2 = bitmapfactory. decoderesource (getresources (), R. drawable. big2); map3 = bitmapfactory. decoderesource (getresources (), R. drawable. big3); map4 = bitmapfactory. decoderesource (getresources (), R. drawable. big4 );}}


 



Big1 to big4 are 1600*900 resolution images, placed in the drawbable-hdpi folder, start the program, and OOM occurs:



 


 05 -08   07 : 44 : 44.372 : E/dalvikvm-heap ( 386 ): 5760000 - Byte External allocation too large For  This process.  05 - 08   07 : 44 : 44.412 : I/dalvikvm-heap (386 ): Clamp target GC heap from 25 . 099 MB 24  . 000 MB  05 - 08   07 : 44 : 44.412 : E/graphicsjni ( 386 ): VM won '  T let us allocate 5760000 bytes  05 - 08  07 : 44 : 44.412 : D/dalvikvm ( 386 ): Gc_for_malloc freed 0 K, 53 % Free 2548 K/5379 K, external 18500 K/ 20548 K, paused 36 ms  05 - 08   07 : 44 : 44.422 : D/skia ( 386 ): --- Decoder-> decode returned False  05 - 08   07 : 44 : 44.422 : D/androidruntime ( 386  ): Shutting Down VM  05 - 08   07 : 44 : 44.432 : W/dalvikvm ( 386 ): Threadid = 1 : Thread exiting with uncaught exception (group = Zero X 40015560  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386  ): Fatal exception: Main  05 - 08   07 : 44 :44.442 : E/androidruntime ( 386  ): Java. Lang. outofmemoryerror: bitmap size exceeds VM budget  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386  ): At Android. Graphics. bitmapfactory. nativedecodeasset (native method)  05 - 08   07 :44 : 44.442 : E/androidruntime ( 386 ): At Android. Graphics. bitmapfactory. decodestream (bitmapfactory. Java: 460  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. Graphics. bitmapfactory. decoderesourcestream (bitmapfactory. Java: 336 )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. Graphics. bitmapfactory. decoderesource (bitmapfactory. Java: 359  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. Graphics. bitmapfactory. decoderesource (bitmapfactory. Java: 385  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At com. mem. Demo. demoactivity. oncreate (demoactivity. Java: 20  )  05 - 08  07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. App. instrumentation. callactivityoncreate (instrumentation. Java: 1047  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. App. activitythread. javasmlaunchactivity (activitythread. Java:1611  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. App. activitythread. handlelaunchactivity (activitythread. Java: 1663  )  05 - 08   07 : 44 :44.442 : E/androidruntime ( 386 ): At Android. App. activitythread. Access $ 1500 (Activitythread. Java: 117  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. App. activitythread $ H. handlemessage (activitythread. Java: 931  ) 05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. OS. handler. dispatchmessage (handler. Java: 99  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. OS. lorule. Loop (lorule. Java: 123  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Android. App. activitythread. Main (activitythread. Java: 3683  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386  ): At java. Lang. Reflect. method. invokenative (native method)  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At java. Lang. Reflect. method. Invoke (method. Java: 507  )  05 - 08  07 : 44 : 44.442 : E/androidruntime ( 386 ): At com. Android. Internal. OS. zygoteinit $ methodandargscaller. Run (zygoteinit. Java: 839  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At com. Android. Internal. OS. zygoteinit. Main (zygoteinit. Java:597  )  05 - 08   07 : 44 : 44.442 : E/androidruntime ( 386 ): At Dalvik. system. nativestart. Main (native method)


 



From the log, memory insufficiency occurs in the decode big4 image. We can print the memory:



 


 Applications memory usage (Kb): uptime:  958383 Realtime: 958383 ** MeminfoIn PID 386 [COM. mem. Demo] ** Native Dalvik other total size:  25144   5379 N/ 30523  Allocated:  20799   2614 N/ 23413   Free : 60   2765 N/2825  (PSS ):  494   426   18494   19414  (Shared dirty ):  2288   1876   5292   9456  (Priv dirty ):  28   17836   18224 


 



From the memory printing, we can see that the current memory has been allocated about 23 MB, combined with the logcat error log, the big4 image requires 5760000 bytes, that is, 5.76 MB of memory, the total memory size is about 29 mb. The default value is emulator2.3.3 in the test environment.
24 m, memory is insufficient to apply for so much, so oom is thrown.



So why does the memory of the android program become insufficient when there are 3 or 4 images in the partition?
The device limit is one aspect. As mentioned above at, the memory limit for each Android device is different. This program has problems on the simulator and on other devices, for example: galaxy will not be faulty. The most important thing is related to the memory occupied by images.
How much memory is used? JAVA does not have the sizeof () function of C and cannot accurately quantify this value. However, there can be a rough calculation method:



 


 



Width * height * bytes occupied by each pixel


 



The width and height are very easy to obtain. What about the bytes occupied by each pixel depends mainly on the decode image method:



 


Bitmap. config alpha_8 each pixel is stored as a single trans1_cy (alpha) channel. bitmap. config argb_4444 this field is deprecated. because of the poor quality of this configuration, it is advised to use argb_8888 instead. bitmap. config argb_8888 each pixel is stored on 4 bytes. bitmap. config rgb_565 each pixel is stored on 2 bytes and only the RGB channels are encoded: Red is stored with 5 bits of precision (32 possible values), green isStore d with 6 bits of precision (64 possible values) and blue is stored with 5 bits of precision.


 



The above is the description of the bitmap. config class in the official documentation. Therefore, if decode is used in argb_8888 mode, each pixel occupies 4 bytes, and rgb_565 occupies 2 bytes.
We can calculate that, after 2.3, the image resources included in the program are all in the argb_8888 mode by default, and the previous method is rgb_565 (uncertain, to be verified ), therefore, the color will have a loss. A typical case is that if there is a gradient, the aperture will appear.
Therefore, the calculation is as follows:



 


1600*900*4 = 5760000


 



This 5760000 is the application number mentioned in the above logcat error log. Of course, it is larger than this number in terms of the memory size printed by the command, this is only the memory of image pixels, and some attributes are not included in variables and classes.



 
Not complete, To be continued...



 


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.