Android Memory Management, OutOfMemoryError

Source: Internet
Author: User

A

  Android Framework enforces a per-process MB memory limit. In some older devices, such as the G1, the limit is less than MB, and more importantly, the memory limit used by the bitmap. Processing an image of an application, it is very easy to reach this limit and get the process of dying with oom abnormally: E/DALVIKVM heap (12517): 1048576 bytes External Allocation This process is too large for E/graphicsjni (12517): VMS will not let us allocate 1048576 bytes/androidruntime (12517): Off VM/DALVIKVM (12517): Subject id = 1: Thread uncaught exception exited (group = 0x4001d7f0) E/androidruntim E (12517): Fatal exception: Main electronics/Androidruntime (12517): Java.lang.OutOfMemoryError: The size of the bitmap exceeds the budget of the VM, this limit is ridiculously low. Device, like one of the 512MB physical RAM nexus, sets the memory limit for each process's foreground activity to only 5% of RAM is a stupid mistake. But anyway, the thing is how to live with us-that is to find out how to fix it. There are two types of memory allocations that are far beyond the limits of

:

One method is to allocate memory from native code. Using the NDK (Local Development Kit) and JNI, it is possible to allocate memory from level C (such as malloc/free or new/deleted) so that the allocation does not count toward the limit of MB. It is true that allocating memory from native code is handy for from Java, but it can be used to store some large amounts of data in RAM (even image data).

Another way in which the artwork and images are using OpenGL texture-texture memory does not count toward the limit   To see how much memory your application really allocates can use Android.os.Debug.getNativeHeapAllocatedSize (), one of the two technologies described above can be used, I can easily assign a single foreground process to 300mb-10 times more than the default of the limit of MB, from the above to use Navtive code allocation memory is not within the limits of 24MB (the texture of the open GL is also using navtive code to allocate memory).

Each Android platform has a different memory limit, from the very beginning of 16M to 24M, and later 32m,64m, perhaps later.

How do you get a single app memory limit size?

Class:activitymanager

Activitymanager Activitymanager = (activitymanager) context.getsystemservice (Context.activity_service); Activitymanager.getmemoryclass ();

Of course, Activitymanager is not limited to this, and many of the tools that are managed by Android programs are sourced from this, or expanded from here.

Android different devices single process available memory is not the same, you can view the/system/build.prop file.

Dalvik.vm.heapstartsize=5m
dalvik.vm.heapgrowthlimit=48m
dalvik.vm.heapsize=256m

The HeapSize parameter represents the maximum memory available to a single process, but if the following parameters are present:

Dalvik.vm.heapgrowthlimit=48m indicates that a single process memory is limited to 48m, which means that only 48m of memory is actually used during program run

Android app is Java, of course, the need for virtual machines, and Android app is with a standalone virtual machine, that is, every application opens a separate virtual machine. The reason for this is that you can avoid a crash of the virtual machine and crash the entire system, but at the cost of more memory. These designs ensure the stability of Android and, under normal circumstances, up to a single program crashes, but the whole system does not crash, and there is never a hint of insufficient memory to appear.

In Android, a process can use only 16M of memory (? ), if you exceed this limit, you will jump out of this anomaly.

For Android specific we should use the ' recycle ' method rather than ' GC ', because ' recycle ' would free the memory at the SA Me time, but calling ' gc ' doesn ' t guaranty to run and free the memory for same time (if it's not too critical, we should n OT call GC in our code) and results can very every time.
One more thing using ' recycle ' is faster than the ' GC ' and it improves the performance.

namely: Bitmap.recycle ();

Biamap=null;

The effect is better than

Biamap=null;

System.GC ();

Monitor memory conditions through the heap tab in DDMS:

In the middle of the 1.Heap view, there is a type called data object, which is the object of a large number of class types in our program.

2. In the data object row, there is a column "total Size" whose value is the amount of memory for all Java data Objects in the current process.

If there is a case where the object reference is not disposed in the code, the total size value of the data object does not come down significantly after each GC, and as the number of operations is increased, the value of total size becomes larger.
Until an upper limit is reached, the process is killed.

B The situation just met today: found in the GetView of the GridView

@Override Public        View GetView (int position, view Convertview, ViewGroup parent) {            final View GridItem = Minflater.       Inflate (R.layout.store_catg_item,null, false); TextView Text = (TextView) Griditem.findviewbyid (r.id.store_catg_item_text);            ImageView cover = (ImageView) Griditem.findviewbyid (r.id.store_catg_item_cover);            Bitmap coverimg = Imageutilities.getcachedcover (magalist                    . Get (position). id+readerconfigures.thumb_suffix_ PLANE);            String title;            if (ISCATG) {                title= magalist.get (position). category;                Text.settext (Title.touppercase ());            } else{                title= magalist.get (position). Pubname;                Text.setvisibility (view.invisible);            }            Griditem.settag (title);            Cover.setimagebitmap (coverimg);            return GridItem;        }

Sliding memory will continue to rise, until outofmemory, the use of holder will not occur after the situation, the specific reason is not carefully searched, marked.

1. For regular developers, there are four ways to refer to Java, such as strong references, soft references, weak references, and virtual references. Some of the more complex programs are likely to have similar outofmemoryerror anomalies in the long run.

2. Do not expect too much of the GC, the object can be displayed without the setting is empty, such as Obj=null,java GC using a graph, to determine whether an object is effective to see the other objects can reach the vertex of the object, the relative to the linked list, the binary tree cost is conceivable.

3.Android the memory allocated for each program can get some memory information of the VM through the runtime class's TotalMemory () Freememory () two methods.

Runtime.getruntime (). Freememory ();

Formatter.formatfilesize (Baseactivity.basecontext,runtime.getruntime (). Freememory ()));//Format output

For system heap memory acquisition, the minimum available heap memory can be obtained through the Getminimumheapsize () method of the Dalvik.vmruntime class, while showing that releasing a soft reference can invoke the Gcsoftreferences () method of the class. Get more running memory.

4. For multi-threaded processing, if there are many concurrent threads and frequent creation and deallocation, you can resolve the thread-created efficiency bottlenecks through the thread pool of the concurrent class.

5. Do not create too many local variables in the loop.

C

The default heap size of android3.0 is 48M. Large Background Pictrue,button icon and the other pictrues used as UI all consume Memory,and even if you have entered Another activity,the resource of the previous activity still be keeped. So you had better isn't use the big pictrue in UI.

In OnDestroy ((bitmapdrawable) Mbtn.getbackground ()). Setcallback (null) clean up the background map. According to reason, the picture resources should have been cleaned out. Look carefully bitmap source code, it actually played the role is to destroy the Java object bitmapdrawable, and Android in order to improve efficiency, bitmap real bitmap data is written in the NDK with C, so with Setcallback can not destroy the bitmap data, You should call Bitmap's recycle () to clean up memory. In OnDestroy Plus ((bitmapdrawable) Mbtn.getbackground ()). Getbitmap (). Recycle (), running down, the memory is ideal, regardless of activity, The resources used are only the current activity, and will not be the same as before to the last activity, all the previously used resources are accumulated in memory.

The new problem arises, however, when the previous activity is returned, a "try to use a recycled bitmap" exception appears. This really pressed the gourd up the scoop Ah, heart that depressed ... There is no way to continue the analysis. It appears that after adding recycle, the bitmap must have a reference in memory, before returning to activity, because the bitmap data has actually been destroyed, so the current situation is caused. After looking at the source of the Setbackgroundresource, it dawned, Android for directly through the resource ID loaded resources is actually done the cache, so the next time you need this resource directly from the cache, which is also for efficiency considerations. But this also causes the use of resources will be in memory, such a design is not very suitable to use a lot of large picture resources of the application, so that the cumulative application of memory spikes is very high. After reading the SDK, I used:

Bitmap BM = Bitmapfactory.decoderesource (This.getresources (), R.drawable.splash);
bitmapdrawable bd = new bitmapdrawable (this.getresources (), BM);

Mbtn.setbackgrounddrawable (BD);

To replace Mbtn.setbackgroundresource (R.drawable.splash).

When destroying, use:

bitmapdrawable BD = (bitmapdrawable) mbtn.getbackground ();

Mbtn.setbackgroundresource (0);//Don't forget to set the background to NULL to avoid used a recycled bitmap error when OnDraw refresh the background

Bd.setcallback (NULL);
Bd.getbitmap (). Recycle ();

This adjustment, to avoid the cache of all the resources in the application, saving valuable memory, but in fact, it does not cause too much efficiency problem, after all, reload the resources is very fast, not a serious impact on performance, in the Xoom I did not feel the difference.

In short, the use of a large number of bitmaps on Android is a painful thing, the existence of memory limitations on the application is a big bottleneck. But not because of choking on food, in fact, understand the mechanism inside it, the application can break through these restrictions. This is just one of the processing methods, and you can also consider bitmapfactory.options insamplesize to reduce memory consumption.

Browse the app for a larger image and use the Jni method to load the image

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.