Android Memory Process Management analysis

Source: Internet
Author: User

 1, the address space of the process

In a 32-bit operating system, the process has an address space of 0 to 4GB,

As follows:



Figure 1

Here are the main instructions for stack and heap:

Stack space (stack and stack) is controlled by the operating system, which mainly stores function addresses, function parameters, local variables, and so on, so the stack space does not need to be large, typically a few megabytes in size.

The use of the heap space is controlled by the programmer, who can manipulate the address space using a function call such as malloc, new, free, and delete. Heap provides memory space for programs to complete a variety of complex tasks, so the space is larger, typically hundreds of MB to several gigabytes. It is because the heap space is managed by programmers that being prone to improper use leads to serious problems.

2 . Relationship between process memory space and Ram

The memory space of a process is only virtual memory (or logical memory), and the program's operation requires real memory, that is, physical memory (RAM). When necessary, the operating system maps the memory (virtual memory) requested in the program's run to ram, allowing the process to use physical memory.

RAM, as an indispensable resource for process operation, has a decisive impact on system performance and stability. In addition, a part of RAM is used by the operating system for his use, such as video memory and so on, and so on is controlled by the operating system, and we do not have to pay too much attention to it, the process is the space to operate the virtual address space, can not directly manipulate the RAM.

As follows:


Figure 2

Introduction to the basic knowledge here, if the reader understand the above knowledge there are obstacles, please good likes and dislikes to fill the basic knowledge, basic knowledge is essential.

3. Process in Android

(1) Native process: The process is implemented in C/s + +, does not contain Dalvik instances, the/system/bin/directory below the program files run in the form of native process. 3,/system/bin/surfaceflinger,/system/bin/rild, Procrank and so on are the native process.

(2) Java process: The process on Android that runs on the Dalvik virtual machine. The host process of the Dalvik virtual machine is created by the fork () system call, so each Java process is present in a native process, so the Java process's memory allocation is more complex than the native process because a virtual machine instance exists in the process. Applications in the 3,android system are basically Java processes, such as desktops, phones, contacts, status bars, and so on.



Figure 3

4. Heap memory of processes in Android

Figure 1 and Figure 4 respectively describe the structure of the native process and Java process, which we programmers need to understand deeply, and the heap space in the process space is what we need to focus on. The heap space is fully controlled by the programmer, and the space we use for malloc, C + + new, and Java new is the heap space, the C + + request memory space in the native heap, and the Java Request memory space in the Dalvik heap.



Figure 4

5. Why is Android Java program prone to oom

This is because the Android system to Dalvik VM HeapSize made a hard limit, when the Java process request Java space exceeds the threshold value, will throw an Oom exception (this threshold can be 48M, 24M, 16M, depending on the model), can be through the ADB shell Getprop | grep dalvik.vm.heapgrowthlimit View this value.

That is, the program OMM does not indicate insufficient RAM, but because the program requested a Java heap object that exceeds the Dalvik VM Heapgrowthlimit. In other words, oom may occur in the case of sufficient RAM.

The design seems a bit unreasonable, but why does Google do it? This is designed to allow the Android system to allow more processes to reside in memory at the same time, so that the program starts without reloading to memory every time, and can give users a quicker response. Forcing each application to use a smaller amount of memory, the very limited amount of RAM on the mobile device allows more apps to reside there. However, there are some large applications that cannot tolerate the limitations of VM Heapgrowthlimit, which will show you how to get your program to jump out of VM Heapgrowthlimit.

6. How Android should handle insufficient RAM

Mentioned in the 5th: Java program oMM does not mean that there is not enough RAM, if the RAM is really insufficient, what happens? At this time the Android memory killer will work, when the RAM is not long, memory killer will kill some of the lower priority process to free up physical memory, so that the high-priority program to get more memory. This is often the case when we analyze log and see the log,5 of the process being killed.



Figure 5

7. How to view RAM usage

You can use the ADB shell cat/proc/meminfo to view RAM usage:

memtotal:396708 KB

memfree:4088 KB

buffers:5212 KB

cached:211164 KB

swapcached:0 KB

active:165984 KB

inactive:193084 KB

Active (anon): 145444 KB

Inactive (anon): 248 KB

Active (file): 20540 KB

Inactive (file): 192836 KB

unevictable:2716 KB

mlocked:0 KB

hightotal:0 KB

highfree:0 KB

lowtotal:396708 KB

lowfree:4088 KB

swaptotal:0 KB

swapfree:0 KB

dirty:0 KB

writeback:0 KB

anonpages:145424 KB

......

......

Some of these fields are explained here:

Memtotal: Total amount of RAM that can be used (less than actual RAM, part of operating system reserved)

Memfree: Unused RAM

Cached: Cache (This is also the memory that the app can apply to)

The total amount of physical memory in the Highttotal:ram is greater than 860M, and can only be used by user-space programs.

Unused memory in Hightfree:ram with an address above 860M

Sum of memory that can be used by both kernel and user space programs in Lowtotal:ram (for 512M ram:lowtotal= memtotal)

Memory not used by kernel and user space programs in Lowfree:ram (for 512M ram:lowfree = memfree)

8. How to view memory information for a process

(1), using adb shell Dumpsys Meminfo + packagename/pid:

As you can see from Figure 6, Com.example.demo as a Java process has 2 heap,native heap and Dalvik heap,

Native heap size is 159508kb,dalvik heap size is 46147KB



Figure 6

(2), using ADB shell Procrank to view process memory information

7:


Figure 7

Explain the meaning of some fields:

Vss-virtual Set Size Virtual memory consumption (contains memory consumed by shared libraries)

Rss-resident Set Size actually uses physical memory (contains memory consumed by shared libraries)

Pss-proportional Set Size Actual physical memory used (proportional allocation of memory consumed by shared libraries)

Uss-unique the Set Size process consumes the physical memory alone (does not contain the memory occupied by the shared library)

In general, memory footprint has the following rules: VSS >= RSS >= PSS >= USS

Note: Procrank can view native processes and Java processes, and Dumpsys meminfo can only view Java processes.

9. How the application bypasses the limitations of DALVIKVM heapsize

For some large-scale applications (such as games), memory usage will be more, it is easy to exceed the VM heapsize limit, then how to ensure that the program does not collapse due to oom?

(1), creating child processes

Create a new process, then we can allocate some objects to the heap of the new process, to achieve the purpose of using more memory for an application, of course, the creation of child processes will increase the overhead, and not all applications are suitable for this, depending on the requirements.

Ways to create child processes: using android:process tags

(2), use JNI to apply for space on native heap (recommended)

The growth of NATIVEHEAP is not limited by the Dalvik VM HeapSize, as can be seen from Figure 6, whose native heap size has far exceeded the limit of Dalvik heap size.

As long as the ram has space left, the programmer can always request space on the native heap, of course, if the RAM is running out, memory killer will kill the process to free up RAM. When you use some software, sometimes it will flash back, it may be the software in the native layer to apply for more memory caused. For example, I have encountered the UC Web in the browsing content of more pages, the reason is that its native heap growth to a relatively large value, occupy a lot of RAM, was memory killer killed.

(3), using memory (part of the operating system reserved RAM as video memory)

Using APIs such as OpenGL textures ,texture memory is not affected by Dalvik VMs HeapSize restrictions, which I have not practiced. Another example is the memory of the graphicbufferallocator application in Android .

 

10. Is the bitmap allocated on the native heap or the Dalvik heap?

A popular point of view is this:

Bitmap is created by the JNI layer, so it should be assigned to the native heap, and in order to explain the bitmap easily lead to Oom, this point is made:

Native Heap size + Dalvik heapsize <= Dalvik vm heapsize

But please take a look at Figure 6,native Heap size 159508KB, far more than Dalvik VM heapsize, So, it turns out that the above view is incorrect.

The right point of view:

As you all know, creating bitmap too much can lead to oom anomalies, and native heapsize is not limited by Dalvik, so it is possible to conclude:

Bitmap can only be allocated on the Dalvik heap, because only in this way can it be explained that bitmap easily leads to Oom.

However, one might say that bitmap is actually created using the Java native method, why is it assigned to the Dalvik heap? In order to solve this problem, we still analyze the source code:

Documents involved:

[Java]View Plaincopyprint?
    1. Framework/base/graphic/java/android/graphics/bitmapfactory.java
    2. Framework/base/core/jni/android/graphics/bitmapfactory.cpp
    3. Framework/base/core/jni/android/graphics/graphics.cpp
framework/base/graphic/java/android/graphics/bitmapfactory.javaframework/base/core/jni/android/graphics/ Bitmapfactory.cppframework/base/core/jni/android/graphics/graphics.cpp

There are several decode*** methods used to create bitmap in Bitmapfactory.java, which will eventually be called:

Private staticnative Bitmap Nativedecodestream (InputStream is, byte[] storage,rect padding,options opts);

Nativedecodestream () calls to the Dedecode method in BitmapFactory.cpp and eventually calls the CreateBitmap method to Graphics.cpp.

Let's take a look at the implementation of the CreateBitmap method:

[Java]View Plaincopyprint?
  1. Jobjectgraphicsjni::createbitmap (jnienv* env, skbitmap* bitmap, Jbytearray buffer,
  2. boolismutable, Jbytearray Ninepatch, int density)
  3. {  
  4. Skassert (bitmap);
  5. Skassert (Bitmap->pixelref ());
  6.    
  7. Jobject obj = Env->newobject (Gbitmap_class, Gbitmap_constructormethodid,
  8. Static_cast<jint> (reinterpret_cast<uintptr_t> (bitmap)),
  9. Buffer, ismutable, ninepatch,density);
  10. hasexception (env); //For the side effectof logging.   
  11. return obj;
  12. }  
Jobjectgraphicsjni::createbitmap (jnienv* env, skbitmap* bitmap, Jbytearray buffer,                                  boolismutable, Jbytearray ninepatch, int density) {    skassert (bitmap);    Skassert (Bitmap->pixelref ());     Jobject obj = Env->newobject (Gbitmap_class, Gbitmap_constructormethodid,           static_cast<jint> ( Reinterpret_cast<uintptr_t> (bitmap)),            buffer, ismutable, ninepatch,density);    Hasexception (env); For the side effectof logging.    return obj;}

From the code you can see that the bitmap object is created by Env->newoject (), to the confusion here, bitmap object is created by the virtual machine, JNIEnv Newoject method returned is a Java object, not native object, So it is assigned to the Dalvik heap.

11. How Java programs can create native objects

You must use JNI, and you should use the C-language malloc or the C + + new keyword. The instance code is as follows:

[Java]View Plaincopyprint?
  1. Jniexport void Jnicalljava_com_example_demo_testmemory_nativemalloc (jnienv *, Jobject)
  2. {  
  3.           
  4. void * p= malloc (1024x768*1024x768* );
  5.    
  6. slogd ("allocate50m Bytes Memory");
  7.    
  8. if (P!=null)
  9.          {         
  10. //memorywill not used without calling memset ()
  11. memset (p,0, 1024x768*1024x768*50);
  12.          }  
  13. Else
  14. Sloge ("mallocfailure." )  );
  15. ....
  16. ....
  17. Free (p); //free Memory   
  18. }  
Jniexport void Jnicalljava_com_example_demo_testmemory_nativemalloc (JNIENV *, jobject) {                 void * p= malloc (1024* 1024*50);          SLOGD ("allocate50m Bytes Memory");          if (P!=null)         {                          //memorywill not used without calling memset ()                   memset (p,0, 1024*1024*50);         }         else                   sloge ("mallocfailure.");   ... free   (p);//free memory}

Or:

[Java]View Plaincopyprint?
  1. Jniexport voidjnicall Java_com_example_demo_testmemory_nativemalloc (jnienv *, Jobject)
  2. {  
  3.           
  4. slogd ("Allocate 50M bytesmemory");
  5. char *p = new char[1024x768 * 1024 * ];
  6. if (P! = NULL)
  7.          {         
  8. //memory would not usedwithout calling memset ()
  9. memset (P, 1, 1024x768*1024x768* );
  10.          }  
  11. Else
  12. Sloge ("newobject failure."  );
  13. ....
  14. ....
  15. Free (p); //free Memory   
  16. }  
Jniexport voidjnicall Java_com_example_demo_testmemory_nativemalloc (jnienv *, jobject) {                 SLOGD ("Allocate 50M Bytesmemory ");         Char *p = new char[1024 * 1024x768 *];         if (P! = NULL)         {//memory would not                          Usedwithout calling memset ()                   memset (p, 1, 1024*1024*50);         }         else                  Sloge ("NewObject failure."); free (p);//free memory}

Here's a little explanation of the memset in the code:

The memory requested by new or malloc is virtual memory and will not be mapped to physical memory immediately after the request, i.e. it will not occupy Ram, and the virtual memory will actually be mapped to ram only after the call to Memset uses memory.

Android Memory Process Management analysis

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.