I am running a relatively simple program that calls mmap() repeatedly to obtain 100MB+ memory (and touch every single page of them). The problem is that this program always triggers the OOM killer in the kernel (based on 3.4) even though there are still plenty of physical pages (2G RAM in total and 1.6G+ is free).
I do see that these two lines of output seem to indicate that there are not many small free blocks left in HighMem (but many big ones are available still):
Normal: 1220*4kB 1034*8kB 791*16kB 547*32kB 289*64kB 130*128kB 39*256kB 9*512kB 5*1024kB 3*2048kB 149*4096kB = 714608kB
HighMem: 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 2*2048kB 254*4096kB = 1046484kB
But I just can't wrap my head around this when the system also says that there are 524288 pages of RAM and 440840 free pages (most are free).
Below is the detailed output. Any help is appreciated!
test_program invoked oom-killer: gfp_mask=0x0, order=0, oom_adj=-17, oom_score_adj=-1000
[<c0011074>] (unwind_backtrace+0x0/0xe0) from [<c00813f0>] (dump_header.isra.16+0x74/0x18c)
[<c00813f0>] (dump_header.isra.16+0x74/0x18c) from [<c0081674>] (oom_kill_process.part.19.constprop.20+0x44/0x268)
[<c0081674>] (oom_kill_process.part.19.constprop.20+0x44/0x268) from [<c0081d64>] (out_of_memory+0x328/0x3f4)
[<c0081d64>] (out_of_memory+0x328/0x3f4) from [<c0081ef0>] (pagefault_out_of_memory+0xc0/0x154)
[<c0081ef0>] (pagefault_out_of_memory+0xc0/0x154) from [<c00120e0>] (do_page_fault+0x1bc/0x244)
[<c00120e0>] (do_page_fault+0x1bc/0x244) from [<c0008364>] (do_DataAbort+0x34/0x98)
[<c0008364>] (do_DataAbort+0x34/0x98) from [<c000d3f4>] (__dabt_usr+0x34/0x40)
Exception stack(0xed479fb0 to 0xed479ff8)
9fa0: aee1cffc aeec2000 0db4da5f aee1d000
9fc0: 00000000 0001b184 00000040 00000059 00000000 00000000 00000000 be9ccacc
9fe0: 00000064 be9cc9f0 0000b037 0000830c 80000030 ffffffff
Mem-info:
Normal per-cpu:
CPU 0: hi: 186, btch: 31 usd: 157
HighMem per-cpu:
CPU 0: hi: 186, btch: 31 usd: 39
active_anon:37727 inactive_anon:936 isolated_anon:0
active_file:4108 inactive_file:25830 isolated_file:0
unevictable:1 dirty:12 writeback:0 unstable:0
free:440273 slab_reclaimable:1457 slab_unreclaimable:2172
mapped:12414 shmem:944 pagetables:752 bounce:0
Normal free:714608kB min:3512kB low:5052kB high:5932kB active_anon:0kB inactive_anon:0kB active_file:788kB inactive_file:1632kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:772160kB mlocked:0kB dirty:48kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:5828kB slab_unreclaimable:8688kB kernel_stack:2032kB pagetables:3008kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 10223 10223
HighMem free:1046484kB min:512kB low:3128kB high:4616kB active_anon:150908kB inactive_anon:3744kB active_file:15644kB inactive_file:101688kB unevictable:4kB isolated(anon):0kB isolated(file):0kB present:1308608kB mlocked:4kB dirty:0kB writeback:0kB mapped:49656kB shmem:3776kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? no
lowmem_reserve[]: 0 0 0
Normal: 1220*4kB 1034*8kB 791*16kB 547*32kB 289*64kB 130*128kB 39*256kB 9*512kB 5*1024kB 3*2048kB 149*4096kB = 714608kB
HighMem: 1*4kB 0*8kB 1*16kB 0*32kB 1*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 2*2048kB 254*4096kB = 1046484kB
30879 total pagecache pages
0 pages in swap cache
Swap cache stats: add 0, delete 0, find 0/1
Free swap = 0kB
Total swap = 0kB
524288 pages of RAM
440840 free pages
9650 reserved pages
3629 slab pages
59279 pages shared
0 pages swap cached
Related
When I installed 30 more apps on my android devices, the screen light up time expires 3s.
Using adb shell ps -t -p to checkout the priority of threads:
USER PID PPID VSIZE RSS PRIO NICE RTPRI SCHED WCHAN
PC NAME system 553 1 6964 856 20 0 0 0
poll_sched 00000000 S /system/bin/imsdatadaemon
system 893 380 1229888 92080 18 -2 0 0 SyS_epoll_ 00000000 S system_server
u0_a94 8515 380 1199228 38548 12 -8 0 0 SyS_epoll_ 00000000 S com.baidu.netdisk
u0_a97 10901 380 848872 98740 12 -8 0 0 SyS_epoll_ 00000000 Scom.hiapk.marketpho
Nice value(priority) of many apps are higher than system_server, which prepares the showing interface when light up screen. I think this result in system_server taking more time to light up screen. In logcat:
01-04 08:02:01.733 893 1276 I DisplayPowerController: Unblocked screen on after 2740 ms
To solve the problem, I want to improve the priority of system_server(original it is THREAD_PRIORITY_FOREGROUND), will any things goes wrong in this way?
public final class SystemServer {
private void run() {
......
// Ensure binder calls into the system always run at foreground priority.
BinderInternal.disableBackgroundScheduling(true);
// Prepare the main looper thread (this thread).
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
android.os.Process.setCanSelfBackground(false);
Looper.prepareMainLooper();
// Initialize native services.
System.loadLibrary("android_servers");
....
}
}
I am trying to monitor CPU usage using the top command in my android phone, using the following command:
Process p = Runtime.getRuntime().exec("top -m 15 -d 1 -n 1");
One of the output's of the top command I got is this:
User 2%, System 9%, IOW 0%, IRQ 0%
User 3 + Nice 0 + Sys 10 + Idle 95 + IOW 0 + IRQ 0 + SIRQ 0 = 108
PID PR CPU% S #THR VSS RSS PCY UID Name
743 0 15% R 1 2416K 948K bg u0_a692 top
15351 0 2% S 79 1921396K 114536K bg u0_a59 com.google.android.googlequicksearchbox:search
167 0 1% S 6 9668K 3512K logd /system/bin/logd
496 0 0% S 1 0K 0K root kworker/0:3
20447 0 0% S 1 0K 0K root kworker/u:34
I am using a Nexus 4 which has a quad core chip i.e. 4 CPUs
Here the total CPU usage is (intuitively) user + system = 11%. However, the top process itself takes 15% of the CPU. It happens most of the time. Here's a graph which I plotted using running the top command at an interval of 1s.
As seen in most cases, the top command uses more CPU than user and system CPU usage combined.
What causes this behavior?
I wanted to calculate how much CPU is used in an idle, sleep state. So, I thought of subtracting the CPU used by the top process from the combined CPU usage of user and system. But, having these kind of output cannot help me to determine exactly how much CPU the phone is using.
Also, is the CPU% of a process the total of user and system? i.e. if a process is utilizing 10% CPU, is it actually using something like 6% user and 4% system CPU?
I use showmap command on a PID, and I can't understand this part in the report:
16384 3752 689 0 3132 0 620 4 /dev/ashmem/dalvik-LinearAlloc (deleted)
2460 1748 934 0 828 0 920 18 /dev/ashmem/dalvik-aux-structure (deleted)
8192 572 572 0 0 0 572 1 /dev/ashmem/dalvik-bitmap-1 (deleted)
8192 0 0 0 0 0 0 1 /dev/ashmem/dalvik-bitmap-2 (deleted)
4100 312 312 0 0 0 312 1 /dev/ashmem/dalvik-card-table (deleted)
502140 14860 14860 0 0 0 14860 3 /dev/ashmem/dalvik-heap (deleted)
1500 280 280 0 0 0 280 1 /dev/ashmem/dalvik-jit-code-cache (deleted)
174764 0 0 0 0 0 0 1 /dev/ashmem/dalvik-mark-stack (deleted)
22148 22148 2141 0 20452 0 1696 1 /dev/ashmem/dalvik-zygote (deleted)
I want to know what data is in the dalvik-LinearAlloc, dalvik-aux-structure, dalvik-bitmap-1, dalvik-bitmap-2, dalvik-card-table, dalvik-mark-stack and dalvik-zygote.
These ashmem cost millions bytes memory, and I want to find a measure to shrink the size of these ashmem.
showmap is dumpping the smap data from one process. The smap is describing the process's memory area's detail. In virtual memory manage system, the memory can be gained by the system API such as mmap, brk. After gaining virtual memory address by these APIs, the address and length will be recorded in the smap.
And let's list each section of the dalvik relative memory usage:
Dalvik Heap section(Heap Management, GC)
dalvik-bitmap-1, dalvik-bitmap-2 is the Dalvik Heap management data stucture. In Dalvik, the GC is marksweep, and 8 bytes memory will be marked(Used or free) as one bit in the bitmap. These two bitmaps will be used as active map(used for marking # runtime) and the other will be used as marked map(used # GC time).
dalvik-mark-stack: For GC mark step use. The mark step will iterate the bitmap, so this is a Breadth-first search which will need a stack.
dalvik-card-table: is used for Dalvik Concurrent GC, in bitmap marking steps, the process will do other tasks which will lead using memory. These card tables is recording the memory dirty after first marking step. You can see the detail by searching mark sweep GC.
dalvik-heap is used for process memory usage
dalvik-zygote is one part of the hole heap, which will not be used # GC. All processes will share these memories such as framework resources.
dalvik-jit is The jit memory used in Dalvik. JIT: just in time, which will convert dex bytecode to machine code which can be executed by CPU.
dalvik-LinearAlloc: is the dalvik's perm memory such as: Method, Class definition datas, thread stack datas. These memory can be setted READONLY after parsing the class definition.
dalvik-aux-structure: auxillary data structures, which will compress the method/class/string const reference. These references will be used # each dex file, but sum of these memory will cost a large memory. So Dalvik create a tmp memory to shared these references.
If you want to analysis your program's memory, I suggest you to use MAT in eclipse. And the native heap usage, you can use mmap to manage.
I'm making application for watching movies which shows images of categories and movies in grid, list and horizontal scroll view.
App has several activities and in every one of them are shown images. Proglem is when user changes activities going only forward, in one point app crashes with OutOfMemory exception.
Using Heap and MAT tools i found that bitmap uses enormous memory of the heap in every activity. On same phones, like Samsung Galaxy S4 and Alcatel OneTouch Idol with full HD display, app crashes in just 2-3 activities. That is crazy :)
So, my question is, how can i overcome this problem with memory?
I know that this is ordinary Android problem but there must be something that I can do to fix this.
Every image is optimazed for its place ( image dimensions are precisely measured before attached to image view).
Cheers.
Do some profiling .
You didn't provide any code or logs .So ,will tell you basic approach which i follow .
start your first activity . Continously run adb shell dumpsys "PID" or "PackageName" .
Get info while you reproduce activity .
execute adb shell " while true ; do dumpsys meminfo 22188 ; done ; " > dumpsysOfsmthn.txt
* MEMINFO in pid 22188 [com.sec.android.smthn] **
Pss Private Private Swapped Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 44 44 0 0 11132 10455 184
Dalvik Heap 19189 18804 0 0 25660 19221 6439
Dalvik Other 3891 3828 0 0
Stack 200 200 0 0
Ashmem 2 0 0 0
Other dev 8168 7844 4 0
.so mmap 1990 1032 508 0
.jar mmap 5 0 4 0
.apk mmap 315 0 124 0
.ttf mmap 21 0 4 0
.dex mmap 6553 248 5584 0
Other mmap 90 4 20 0
Unknown 5743 5740 0 0
TOTAL 46211 37744 6248 0 36792 29676 6623
Objects
Views: 39 ViewRootImpl: 1
AppContexts: 4 Activities: 1
Assets: 3 AssetManagers: 3
Local Binders: 78 Proxy Binders: 42
Death Recipients: 2
OpenSSL Sockets: 0
SQL
MEMORY_USED: 286
PAGECACHE_OVERFLOW: 53 MALLOC_SIZE: 62
DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 24 53 2/17/3 /data/data/com.sec.android.smthn/databases/sns.db
4 32 55 1/13/2 /data/data/com.sec.android.smthn/databases/picasa.db
4 36 27 10/17/3 /data/data/com.sec.android.smthn/databases/local.db
Applications Memory Usage (kB):
Uptime: 31556347 Realtime: 96096816
Check which part of portion is increasing constantly .
It could be ViewRootImpl or activity context or anything .
Above information might get you to some clue .
As told take heapdump analyse it with MAT or JHAT .
Mat is awewome tool IMHO .
you should look for memory leaks caused by:
Long-lived references to an Activity, Context, View, Drawable, and other objects that may hold a reference to the container Activity or Context.
Non-static inner classes (such as a Runnable, which can hold the Activity instance).
Caches that hold objects longer than necessary.
Leak can be caused by any Object.Generally bitmaps are big. And if the out-of memory occurs very easily then you need to check on heavy objects like bitmaps.
For MAT and Leaks understanding Click this
Also this .
Also apart from above things you can also use DDMS allocation tracker to get more clue > yeah nothing can get better data than MAT .
Also check this post . Very informative
I want to acquirećAndroid Device VRAM size.
Is there a method for acquisition from the program?
Let's do some calculation using Nexus One:
Screen resolution is 480x800. So minimum required video memory size would be:
400 * 800 * 4 bytes = 1536000 bytes
Assuming that driver may (and normally should) use several buffers, we should also expect values like:
1536000 * 2 bytes = 3072000 bytes
1536000 * 3 bytes = 4608000 bytes
etc...
It would be weird to have values that are not multiple of 1536000 (or W x H x 4 in general).
After some searches on Android internals I've found this documentation :
...Android makes two requirements of the driver: a linear address space of mappable memory that it can write to directly...accessing the driver by calling open on /dev/fb0...
So I tried and take size of /dev/graphics/fb0 file (on my device there is no /dev/fb0).
But a direct approach doesn't work:
File file = new File("/dev/graphics/fb0");
file.length(); // ==0, doesn't work, no read access
Using next trick you can get actual size of fb0:
>adb pull /dev/graphics/fb0
1659 KB/s (4608000 bytes in 2.712s)
Video memory is ~4mb (Nexus One). Let's check if this is multiple of Nexus screen size:
4608000/1536000 = 3
It looks like a right value. And we also can say that driver uses three screen buffers.
So, as a conclusion, you can detect video memory size using adb, but you can't use this approach from your android application in runtime due to file access restrictions.
You typically do not have a dedicated "VRAM" on mobile devices. At least you don't have it with PowerVR architectures (wich totally dominate the market with their MBX and SGX cores).
That is, the OpenGL driver allocates normal RAM until you run out of it, and the more you allocate the less you have left for your application.
The Android/OpenGL APIs don't offer explicit methods to read the VRAM size from a given device.
Poor man solution:
You could try to infer the VRAM size in an empiric way adding 1MB texture until you get an out of memory error from gl.glGetError().
From your "dmesg" output u can read off the VRAM, so for my Tablet:
> [ 0.000000] Machine: TDM3730 [ 0.000000] Reserving 12582912
> bytes SDRAM for VRAM
>
> 7>[ 3.929962] VRAM: checking region 9f400000 3072
> <4>[ 3.929992] Failed. Allocating 4194304 bytes for fb 0
> <7>[ 3.935333] VRAM: alloc mem type 0 size 4194304 paddr dec2bd4c
> <7>[ 3.935485] VRAM: checking region 9f400000 3072
> <7>[ 3.935485] VRAM: found 9f400000, end a0000000
> <6>[ 3.936584] android_usb gadget: high speed config #1: android
> <4>[ 3.960113] allocating 4194304 bytes for fb 1
or details at:
http://pastebin.com/jQSXQqHh
Is simple just count how many Mb ram that from usable to real capacity of the ram, example for my lenovo a369i has 512 RAM Module, but in setting app only showing 471 Mb usable so the 41Mb left is reserved for the GPU, so the conclusion is my a369i has 41Mb vram
This method is based from shared graphics memory (wiki)
I suspect that android.os.StatFs is what you're looking for:
http://developer.android.com/reference/android/os/StatFs.html