Android内存检测

Android内存检测
Android内存检测

Android 内存检测

1. Introduction

Android对内存的使用包括内存泄漏和内存越界,内存泄漏会导致系统内存减少,最终分配不到内存,这样大的程序就不能运行,甚至系统没有内存而崩溃。Android中kernel和应用程序都可能会有内存泄漏和越界。对于Java代码,在越界的时候虚拟机会加以检查并抛出异常。而对于C/C++代码,越界的时候就悄无声息地让程序出错或crash

2. 内核中的内存泄漏检测

内核中已经内嵌了内存泄漏的代码,编译的时候需要打开配置

代码及帮助位置:

其中kmemcheck是检测内存越界等错误的,目前只支持X86

kernel/Documentation/kmemleak.txt

kernel/Documentation/kmemcheck.txt

kernel/mm/kmemleak.c

kernel/mm/kmemcheck.c

内核配置

CONFIG_DEBUG_KMEMLEAK=y

CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=1000

其中CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE的大小跟board的kernel porting相关,

有的不需要定义,有的需要定义大一点,可以在kmemleak.c中模块初始化代码中调试.

kmemleak模块初始化成功后,会产生/sys/kernel/debug/kmemleak这个文件

操作命令如下:

#su

#echo scan > /sys/kernel/debug/kmemleak扫描泄漏

#cat /sys/kernel/debug/kmemleak 查看泄漏

#echo clear > /sys/kernel/debug/kmemleak清除结果

当出现泄漏后,会有提示,比如

unreferenced object 0xd25f3cc0 (size 64):

comm "Binder_5", pid 1257, jiffies 68676 (age 3105.280s)

hex dump (first 32 bytes):

00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

backtrace:

[] create_object+0x12c/0x248

[] kmemleak_alloc+0x88/0xcc

[] kmem_cache_alloc_trace+0x13c/0x1f4

[] ion_carveout_heap_map_dma+0x34/0xcc

[] ion_alloc+0x170/0x3f0

[] ion_ioctl+0xc0/0x410

[] do_vfs_ioctl+0x4f4/0x568

[] sys_ioctl+0x48/0x6c

[] ret_fast_syscall+0x0/0x48

[] 0xffffffff

通过backtrace可以看到泄漏的地方是ion_carveout_heap_map_dma,通过看代码发现是

ion_carveout_heap_unmap_dma的时候少释放了内存。

kmemleak的原理这里不作介绍,大致原理扫描是否有指针指向这段内存,没有则认为是泄漏,这也导致有的地方会误报,比如内存重复使用带引用次数的,

int offset = 4;

char *real = kmalloc(size, flag) + offset

kfree(real - offset)

在内核中这种特殊的地方很少,大部分检测出来的都是真的泄漏了。

3. 内核中的内存越界检测

参考: kernel/Documentation/vm/slub.txt

内核配置为使用slub作为内存分配器,slub本身提供了检查越界的接口,如果kernel刚启动就要检查内存破坏,则需要编译的时候配置CONFIG_SLUB_DEBUG_ON=y

否则可以使用slabinfo –d A来打开检查功能,打开后,slub会在内存后面加一些关键字,释放的时候会检查是否被破坏,如果破坏了,

check_bytes_and_report中print一个警告,

可以修改check_bytes_and_report后面部分的代码,在debug版本中加入panic让系统死机来报告内存越界错误。

static int check_bytes_and_report(struct kmem_cache *s, struct page *page,

u8 *object, char *what,

u8 *start, unsigned int value, unsigned int bytes)

{

u8 *fault;

u8 *end;

fault = memchr_inv(start, value, bytes);

if (!fault)

return 1;

end = start + bytes;

while (end > fault && end[-1] == value)

end--;

slab_bug(s, "%s overwritten", what);

printk(KERN_WARN "INFO: 0x%p-0x%p. First byte 0x%x instead of 0x%x\n",

fault, end - 1, fault[0], value);

print_trailer(s, page, object);

restore_bytes(s, what, value, fault, end);

return 0;

}

比如显示如下:

BUG kmalloc-8: Redzone overwritten

--------------------------------------------------------------------

INFO: 0xc90f6d28-0xc90f6d2b. First byte 0x00 instead of 0xcc INFO: Slab 0xc528c530 flags=0x400000c3 inuse=61 fp=0xc90f6d58 INFO: Object 0xc90f6d20 @offset=3360 fp=0xc90f6d58 INFO: Allocated in get_modalias+0x61/0xf5 age=53 cpu=1 pid=554

Bytes b4 0xc90f6d10: 00 00 00 00 00 00 00 00 5a 5a 5a 5a 5a 5a 5a 5a ........ZZZZZZZZ Object 0xc90f6d20: 31 30 31 39 2e 30 30 35 1019.005 Redzone 0xc90f6d28: 00 cc cc cc . Padding 0xc90f6d50: 5a 5a 5a 5a 5a 5a 5a 5a ZZZZZZZZ

[] dump_trace+0x63/0x1eb

[] show_trace_log_lvl+0x1a/0x2f

[] show_trace+0x12/0x14

[] dump_stack+0x16/0x18

[] object_err+0x143/0x14b

[] check_object+0x66/0x234

[] __slab_free+0x239/0x384

[] kfree+0xa6/0xc6

[] get_modalias+0xb9/0xf5

[] dmi_dev_uevent+0x27/0x3c

[] dev_uevent+0x1ad/0x1da

[] kobject_uevent_env+0x20a/0x45b

[] kobject_uevent+0xa/0xf

[] store_uevent+0x4f/0x58

[] dev_attr_store+0x29/0x2f

[] sysfs_write_file+0x16e/0x19c

[] vfs_write+0xd1/0x15a

[] sys_write+0x3d/0x72

[] sysenter_past_esp+0x5f/0x99

[] 0xb7f7b410

4. 应用的内存简介

4.1. 查看系统内存

可以使用ddms来查看系统的内存使用情况,是靠读取/proc/meminfo来分析出来的框图。

4.2. 进程内存查看

单个进程的内存使用情况可以检查 proc//status

再具体可以看

/proc//statm

/proc//maps

/proc//smaps

top命令也可以显示VSS和 RSS

VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)

RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)

PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)

USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存

一般来说内存占用大小有如下规律:VSS >= RSS >= PSS >= USS

# procrank -h

Usage: procrank [ -W ] [ -v | -r | -p | -u | -h ]

-v Sort by VSS.

-r Sort by RSS.

-p Sort by PSS.

-u Sort by USS.

(Default sort order is PSS.)

-R Reverse sort order (default is descending).

-w Display statistics for working set only.

-W Reset working set of all processes.

-h Display this help screen.

And here is some sample output:

# procrank

PID Vss Rss Pss Uss cmdline

1217 36848K 35648K 17983K 13956K system_server

1276 32200K 32200K 14048K 10116K android.process.acore

1189 26920K 26920K 9293K 5500K zygote

1321 20328K 20328K 4743K 2344K android.process.media

1356 20360K 20360K 4621K 2148K com.android.email

1303 20184K 20184K 4381K 1724K com.android.settings

1271 19888K 19888K 4297K 1764K https://www.360docs.net/doc/0519204544.html,tin

1332 19560K 19560K 3993K 1620K com.android.alarmclock

1187 5068K 5068K 2119K 1476K /system/bin/mediaserver

1384 436K 436K 248K 236K procrank

1 212K 212K 200K 200K /init

753 572K 572K 171K 136K /system/bin/rild

748 340K 340K 163K 152K /system/bin/sh

751 388K 388K 156K 140K /system/bin/vold

1215 148K 148K 136K 136K /sbin/adbd

757 352K 352K 117K 92K /system/bin/dbus-daemon

760 404K 404K 104K 80K /system/bin/keystore

759 312K 312K 102K 88K /system/bin/installd

749 288K 288K 96K 84K /system/bin/servicemanager

752 244K 244K 71K 60K /system/bin/debuggerd

详细解释见如下:

Android has a tool calledprocrank (/system/xbin/procrank), which lists out the memory usage of Linux processes in order from highest to lowest usage. The sizes reported per process are VSS, RSS, PSS, and USS.

For the sake of simplicity in this description, memory will be expressed in terms of pages, rather than bytes. Linux systems like ours manage memory in 4096 byte pages at the lowest level.

VSS (reported as VSZ from ps) isthe total accessible address space of a process. This size also includes memory that may not be resident in RAM like mallocs that have been allocated but not written to. VSS is of very little use for determing real memory usage of a process. RSS is the total memory actually held in RAM for a process. RSS can be misleading, because it reports the total all of the shared libraries that the process uses, even though a shared library is only loaded into memory once regardless of how many processes use it. RSS is not an accurate representation of the memory usage for a single process.

PSS differs from RSS in that it reports the proportional size of its shared libraries, i.e. if three processes all use a shared library that has 30 pages, that library will only contribute 10 pages to the PSS that is reported for each of the three processes. PSS is a very useful number because when the PSS for all processes in the system are summed together, that is a good representation for the total memory usage in the system. When a process is killed, the shared libraries that contributed to its PSS will be proportionally distributed to the PSS totals for the remaining processes still using that library. In this way PSS can be slightly misleading, because when a process is killed, PSS does not accurately represent the memory returned to the overall system.

USS is the total private memory for a process, i.e. that memory that is completely unique to that process. USS is an extremely useful number because it indicates the true incremental cost of running a particular process. When a process is killed, the USS is the total memory that is actually returned to the system. USS is the best number to watch when initially suspicious of memory leaks in a process.

4.3. JAVA虚拟机的堆

Dalvik Heap靠zygote预先加载了类和数据,当zygote fork一个android应用的时候,新的应用得到这个Heap的copy-on-write mapping 5. Debugging Android application memory

5.1. JAVA的内存泄漏和越界

JAVA语言本身对内存越界是敏感的,JAVA中内存越界虚拟机抛出异常。

JAVA的内存泄漏的检测可以通过在eclipse中安装Memory Analyzer Tool(MAT)来插件来进行。

这里只简单说下步骤,需要完整的SDK和eclipse环境

1.打开Eclipse

2.选择 Help->Install New Software;

3.在work with中添加站点:MAT -https://www.360docs.net/doc/0519204544.html,/mat/1.3/update-site/

(这个地址可能会变化,但是新的地址可以在官方网站上找到

https://www.360docs.net/doc/0519204544.html,/mat/downloads.php)

4.生成.Hprof文件:插入SD卡,在Eclipse中的DDMS中选择要测试的进程,然后点击

Update Heap 和Dump HPROF file两个按钮。

.Hprof 文件会自动保存在SD卡上

把 .hprof文件拷贝到PC上的\ android-sdk-windows\tools目录下。这个由DDMS生成的

文件不能直接在MAT打开,需要转换。进入 android-sdk-windows \tools所在目录,

并输入命令hprof-conv xxxxx.hprof yyyyy.hprof,其中xxxxx.hprof为原始文件,

yyyyy.hprof为转换过后的文件。

5..打开MAT:

在Eclipse中点击Windows->Open Perspective->Other->Memory Analysis

6.导入.hprof文件

在MAT中点击 File->Open File打开刚刚转换而得到的yyyyy.hprof文件,并Cancel掉自

动生成报告,点击Dominator Tree,并按Package分组,选择自己所定义的Package类点右键,在弹出菜单中选择List objects->With incoming references。

这时会列出所有可疑类,右键点击某一项,并选择Path to GC Roots->exclude weak/soft references,会进一步筛选出跟程序相关的所有有内存泄露的类。据此,可以追踪到代码中的某一个产生泄露的类。

5.2. Native的内存泄漏和越界

Android的native内存泄漏可以用valgrind工具,但是这个工具在android里运行太慢,Android里的bionic库提供了内存泄漏的检测方法

见bionic/libc/bionic/malloc_debug_common.c里的注释.

所有的native内存分配函数都在libc库里,为了跟踪,需要使用这个库的特别版版本libc_malloc_debug_leak.so和libc_malloc_debug_qemu.so,可以看看eng或这user-debug版中的/system/lib/下是否有这两个文件,其中libc_malloc_debug_qemu.so是模拟器用的。

在malloc_debug_common.c中的内存调试靠读取属性libc.debug.malloc来控制的,属性值含义如下:

libc.debug.malloc 1 检测内存泄漏

libc.debug.malloc 5 分配的内存用0xeb填充,释放的内存用0xef填充

libc.debug.malloc 10 内存分配打pre-和post- 的桩子,可以检测内存的overruns

libc.debug.malloc 20 SDK模拟器上检测内存用

简单的内存泄漏检测可以通过adb shell写为

#setprop libc.debug.malloc 1

#stop

#start

然后logcat就可以显示内存泄漏,有的server可能stop杀不掉,为了开机就启动,可以在开机的时候就设置属性。

可以修改init.rc,增加setprop libc.debug.malloc 10属性编译烧机,

或者

#adb remount

#vi system/build.prop增加libc.debug.malloc=10属性

除了通过logcat看,也可以配置ddms,通过ddms来看内存泄漏。

可以在~\.android\ ddms.cfg 文件后面添加native=true这样打开ddms就可以看到Native Heap了

点击snapshot current native heap usageke根据提示在symbol search path里输入相应库的符号表路径就行了,需要在启动ddms前把

arm-linux-androideabi-addr2linux所在的路径加到PATH环境变量中,如果shell中已经运行过编译android前的. build/enxxx lunch 等操作,则已经加到PATH中去了。

找到泄漏后,根据提示的backtrace地址,可以用NDK中的arm-linux-androideabi-addr2line工具算出对应的函数地址,也可以排列成用tombstone 的格式,用stacktrace工具求出函数调用关系。在上图ddms中,在symbol search path里填入编译是的库的路径,

可能可以直接显示出函数的名字。

在libc初始化的时候,注册了atexit函数(__libc_init函数),所以程序退出的时候会调用见native的内存泄漏在程序退出的时候会调用到malloc_debug_fini

void malloc_debug_fini(void)

{

/* We need to finalize malloc iff we implement here custom

* malloc routines (i.e. USE_DL_PREFIX is defined) for libc.so */

#if defined(USE_DL_PREFIX) && !defined(LIBC_STATIC)

if (pthread_once(&malloc_fini_once_ctl, malloc_fini_impl)) {

error_log("Unable to finalize malloc_debug component.");

}

#endif // USE_DL_PREFIX && !LIBC_STATIC

}

对于mediaserver等进程,它一直不退出,就无法显示出泄漏的内存,用kill的方式也不能让atexit注册的退出函数得到调用,所以无法自动显示内存错误,针对server这种情况,有两种方式来处理,这两种方式也适用于其它的可以退出的进程。

第一种是在程序中加入检查泄漏的代码,通过调用get_malloc_leak_info()来查看是否总是不停地增长的。

第二种方法如下: server name为固定的一个server的名字(可以用service list查看)

1. 保存 /proc//maps文件到PC机器

2. ps

3. dumpsys -m > 1.mm

4. 操作手机

5. dumpsys -m > 2.mm

然后比较1.mm和2.mm,看看2比1多了那些内容

内容如下

size 31379, dup 1, 0x400f5dc8, 0x400ae2c6, 0x413afa96, 0x400ab020, 0x400aab74

其中size后面的数字表示分配的大小, dup分配的次数。

通过第1步中的maps文件,可以看到该进程每个库加载的起始地址

比如。0x413afa96是落在camera.sc8825.so的代码段内的,由此计算其指令在文件内的

偏移量,0x413afa96 - 0x41391000 = 0x1ea96。然后用addr2line就可以查看这条指

令对应的源码在哪个文件的哪个位置。

41391000-413e9000 r-xp 00000000 b3:0c

535 /system/lib/hw/camera.sc8825.so

$ arm-linux-androideabi-addr2line -e

out/target/product/sp8825ea/symbols/system/lib/hw/camera.sc8825.so 0x1ea96

如果是应用这则要用dumpheap命令

am dumpheap -n <应用的名字> /data/1.mm

am dumpheap -n <应用的名字> /data/2.mm

上面addr2line的过程可以用脚本去自动实现

也可以随时调用dumpsys meminfo $package_name or $pid 看看消耗内存的趋势

在stop 之后,可以用ps看看哪些server还是没被杀掉,这样的server要调试的要需要主动kill掉,然后再start才可以,或者在开机的时候就设置属性libc_debug_malloc为1

android避免内存泄露

1、数据库的cursor没有关闭 2、构造adapter没有使用缓存contentview 衍生的listview优化问题:减少创建View的对象,充分使用contentview,可以使用静态类来处理优化getView的过程 3、Bitmap对象不使用时采用recycle()释放内存 4、Activity中的对象生命周期大于Activity 调式方法:DDMS->HEAPSIZE->adtaobject->total size Android应用程序被限制在16MB的堆上运行,至少在T-Mobile G1上是这样。对于手机来说,这是很大的内存了;但对于一些开发人员来说,这算是较小的了。即使你不打算使用掉所有的内存,但是,你也应该尽可能少地使用内存,来确保其它应用程序得以运行。Android在内存中保留更多的应用程序,对于用户来说,程序间切换就能更快。作为我(英文作者)工作的一部分,我调查了Android应用程序的内存泄露问题,并发现这些内存泄露大多数都是由于相同的错误导致的,即:对Context拥有较长时间的引用。 在Android上,Context常用于许多操作,更多的时候是加载和访问资源。这就是为什么所有的Widget在它们的构造函数里接受一个Context的参数。在一个正常的Android应用程序里,你会看到两种Context类型,Activity和Application。而一般在需要一个Context的类和方法里,往往传入的是第一种: Java代码 @Override protected void onCreate(Bundle state) { super.onCreate(state); TextView label = new TextView(this); label.setText("Leaks are bad");

浅谈Android(安卓)

浅谈Android--嵌入式操作系统 Android(读音:[??ndr?id],中文俗称安卓)是一个以Linux为基础的半开源操作系统,主要用于移动设备,由Google成立的Open Handset Alliance (OHA,开放手持设备联盟)持续领导与开发中。 --题记.维基百科说起嵌入式系统,曾经在保罗大叔的著作《黑客与画家》里看到多次,然后不明所以,就去查了嵌入式系统。如果说嵌入式系统给我的第一印象是硬件,那么是我还不知道嵌入式在我生活里已经出现了很多年了。 大到冰箱,自动存款机(ATM),小到电子手表,遥控器。在维基百科解答后,我对嵌入式直观的理解,是一种特定的植入硬件并极具针对性的计算机系统。 后来慢慢了解嵌入式的软件方面,就知道了嵌入式操作系统,而其中的佼佼者,就是如今已经超越ios,占据半壁江山的Android。 之所以会说Android,原因有二:一,因为Android如今炙手可热,在新一季度的日本手机软件营销额上,以Java等语言为Android系统开发的Apps,疯狂揽金,李开复断言在两年内,中国内地手机游戏软件市场,将会百花齐放;二,我虽并非研究Java也非致力于Android系统,但是Android系统的内核,却是我所熟悉的Linux内核。而我将自己的开发平台转移到Linux系统,并以Python,Perl以及Lisp语言作为未来的生存工具,所以,就让我们谈一谈Android。 题记中套用维基百科对于Android的介绍,主要的目的,就是为了澄清一件事实“认知”——Android并没有真正的中文名。 Google并没有为Android命名,只有为其版本取名,且翻译成中文:4.2.x Jelly Bean 果冻豆,4.0.x Ice Cream Sandwich 冰激凌三明治,3.x.x Honey

ANDROID BITMAP内存限制OOM,OUT OF MEMORY

ANDROID BITMAP内存限制OOM OUT OF MEMORY 在编写Android程序的时候,我们总是难免会碰到OOM的错误,那么这个错误究竟是怎么来的呢?我们先来看一下这段异常信息: 08-14 05:15:04.764: ERROR/dalvikvm-heap(264): 3528000-byte external allocation too large for this process. 08-14 05:15:04.764: ERROR/(264): VM won't let us allocate 3528000 bytes 08-14 05:15:04.764: DEBUG/skia(264): --- decoder->decode returned false 08-14 05:15:04.774: DEBUG/AndroidRuntime(264): Shutting down VM 08-14 05:15:04.774: WARN/dalvikvm(264): threadid=3: thread exiting with uncaught exception (group=0x4001b188) 08-14 05:15:04.774: ERROR/AndroidRuntime(264): Uncaught handler: thread main exiting due to uncaught exception 08-14 05:15:04.794: ERROR/AndroidRuntime(264): https://www.360docs.net/doc/0519204544.html,ng.OutOfMemoryError: bitmap size exceeds VM budget 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:447) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:323) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:346) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.graphics.BitmapFactory.decodeResource(BitmapFactory.java:372) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at com.xixun.test.HelloListView.onCreate(HelloListView.java:33) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.access$2200(ActivityThread.java:119) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.os.Handler.dispatchMessage(Handler.java:99) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.os.Looper.loop(Looper.java:123) 08-14 05:15:04.794: ERROR/AndroidRuntime(264): at android.app.ActivityThread.main(ActivityThread.java:4363)

Android的原理:关于应用自启动,占内存那些问题

Android的原理-不需要太多的剩余内存 Android用RAM的方式,跟windows、WM、Sybiam是两回事。在Android里,RAM被用满了是件好事。它意味着你可以快速打开之前打开的软件,回到之前的位置。所以Android 很有效的使用RAM,很多用户看到他们的RAM满了,就认为拖慢了他们的手机。而实际上,退出后重启这些程序才真正拖慢了手机的响应。而且这些自动杀进程的软件本身是个时刻活跃的进程,它始终在后台保持活跃使得CPU难以消停,反而增加了耗电量。 不用在意剩余内存的大小.其实很多人都是把使用其他系统的习惯带过来来了.安卓Android大多应用没有退出的设计其实是有道理的,这和系统对进程的调度机制有关系.如果你知道java,就能更清楚这机制了.其实和java的垃圾回收机制类似,系统有一个规则来回收内存.进行内存调度有个阀值,只有低于这个值系统才会按一个列表来关闭用户不需要的东西.当然这个值默认设置得很小,所以你会看到内存老在很少的数值徘徊.但事实上他并不影响速度.相反加快了下次启动应用的速度.这本来就是安卓Android标榜的优势之一,如果人为去关闭进程,没有太大必要.特别是自动关进程的软件. 到这里有人会说了,那为什么内存少的时候运行大型程序会慢呢?其实很简单,在内存剩余不多时打开大型程序,会触发系统自身的调进程调度策略,这是十分消耗系统资源的操作,特别是在一个程序频繁向系统申请内存的时候.这种情况下系统并不会关闭所有打开的进程,而是选择性关闭,频繁的调度自然会拖慢系统.所以,论坛上有个更改内存阀值的程序可以有一定改善. 但改动也可能带来一些问题,取决于值的设定. 那么,进程管理软件有无必要呢?有的.就是在运行大型程序之前,你可以手动关闭一些进程释放内存,可以显著的提高运行速度.但一些小程序,完全可交由系统自己管理.谈到这里,可能有的朋友会问,如果不关程序是不是会更耗电.我就说说安卓Android后台的原理,你就明白了.安卓Android 的应用在被切换到后台时,它其实已经被暂停了,并不会消耗cpu资源,只保留了运行状态.所以为什么有的程序切出去重进会到主界面.但是,一个程序如果想要在后台处理些东西,如音乐播放,它就会开启一个服务.服务可在后台持续运行,所以在后台耗电的也只有带服务的应用了.这个在进程管理软件里能看到,标签是service.所以没有带服务的应用在后台是完全不耗电的,没有必要关闭.这种设计本来就是一个非常好的设计,下次启动程序时,会更快,因为不需要读取界面资源,何必要关掉他们抹杀这个安卓Android的优点呢? 还有一个.为什么安卓Android一个应用看起来那么耗内存.大家知道,安卓Android上的应用是java,当然需要虚拟机,而安卓Android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机.这样设计的原因是可以避免虚拟机崩溃导致整个系统崩溃,但代价就是需要更多内存. 以上这些设计确保了安卓Android的稳定性,正常情况下最多单个程序崩溃,但整个系统不会崩溃,也永远没有内存不足的提示出现.大家可能是被windows毒害得太深了,总想保留更多的内存,但实际上这并不一定会提升速度,相反却丧失了程序启动快的这一系统特色,很没必要.

Android开发内存泄漏及检查工具使用培训资料

Android 开发内存泄漏及检查工具使用培 训资料

目录 1内存泄露 (3) 1.1 内存泄露的概念 (3) 1.2 开发人员注意事项 (4) 1.3 Android(java)中常见的引起内存泄露的代码示例 (4) 1.3.1查询数据库没有关闭游标 (6) 1.3.2 构造Adapter时,没有使用缓存的convertView (6) 1.3.3 Bitmap对象不在使用时调用recycle()释放内存 (7) 1.3.4 释放对象的引用 (8) 1.3.5 其他 (9) 2内存泄露的分析工具 (9) 2.1 内存监测工具DDMS --> Heap (9) 2.2 内存分析工具MAT (Memory Analyzer Tool) (10) 2.2.1 生成.hprof文件 (10) 2.2.2 使用MA T导入.hprof文件 (11) 2.2.3 使用MA T的视图工具分析内存 (12)

1内存泄露 Android 应用程序开发以Java语言为主,而Java编程中一个非常重要但却经常被忽视的问题就是内存使用的问题。Java的垃圾回收机制(Garbage Collection 以下简称GC)使得很多开发者并不关心内存使用的生命周期,只顾着申请内存,却不手动释放废弃的内存,而造成内存泄露,引起很多问题,甚至程序崩溃。Android的虚拟机Dalvik VM和java虚拟机JVM没有什么太大的区别,只是在字节码上稍做优化,所以Android应用开发中同样会出现内存泄露的问题。而且由于Android智能平台主要用于嵌入式产品开发,可用的内存资源更加稀少,所以对于我们Android应用开发人员来说,就更该了解Android程序的内存管理机制,避免内存泄露的发生。 1.1 内存泄露的概念 在计算机科学中,内存泄漏(memory leak)指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况。内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段内存的控制,因而造成了内存的浪费。内存泄漏与许多其他问题有着相似的症状,并且通常情况下只能由那些可以获得程序源代码的程序员才可以分析出来。然而,有不少人习惯于把任何不需要的内存使用的增加描述为内存泄漏,严格意义上来说这是不准确的。 一般我们常说的内存泄漏是指堆内存的泄漏。堆内存是指程序从堆中分配的,大小任意的(内存块的大小可以在程序运行期决定),使用完后必须显式释放的内存。应用程序一般使用malloc,calloc,realloc,new等函数从堆中分配到一块内存,使用完后,程序必须负责相应的调用free或delete释放该内存块,否则,这块内存就不能被再次使用,我们就说这块内存泄漏了。 这里我们只简单的理解,在java程序中,如果已经不再使用一个对象,但是仍然有引用指向它,GC就无法收回它,当然该对象占用的内存就无法再被使用,这就造成内存泄露。可能一个实例对象的内存泄露很小,并不会引起很大的问题。但是如果程序反复做此操作或者长期运行,造成内存不断泄露,终究会使程序无内存可用,只好被系统kill掉。在以下情况,内存泄漏导致较严重的后果: * 程序运行后置之不理,并且随着时间的流失消耗越来越多的内存(比如服务器上的后台任务,尤其是嵌入式系统中的后台任务,这些任务可能被运行后很多年内都置之不理); * 新的内存被频繁地分配,比如当显示电脑游戏或动画视频画面时; * 程序能够请求未被释放的内存(比如共享内存),甚至是在程序终止的时候; * 泄漏在操作系统内部发生; * 泄漏在系统关键驱动中发生; * 内存非常有限,比如在嵌入式系统或便携设备中; * 当运行于一个终止时内存并不自动释放的操作系统(比如AmigaOS)之上,而且一旦丢失只能通过重启来恢复。

Android 应用程序内存泄漏的分析

Android 应用程序内存泄漏的分析以前在学校里学习Java的时候,总是看到说,java是由垃圾收集器(GC)来管理内存回收的,所以当时形成的观念是Java不会产生内存泄漏,我们可以只管去申请内存,不需要关注内存回收,GC会帮我们完成。呵呵,很幼稚的想法,GC没那么聪明啊,理论及事实证明,我们的Java程序也是会有内存泄漏的。 (一)Java内存泄漏从何而来 一般来说内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,没有将其释放,或者是在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值);另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。 (二)需要的工具 1.DDMS—Update heap Gause GC Heap 是DDMS自带的一个很不错的内存监控工具,下图红色框中最左边的图标就是该 工具的启动按钮,它能在Heap视图中显示选中进程的当前内存使用的详细情况。下图 框中最右边的是GC工具,很多时候我们使用Heap监控内存的时候要借助GC工具,点 击一次GC按钮就相当于向VM请求了一次GC操作。中间的按钮是Dump HPROF file,它 的功能相当于给内存拍一张照,然后将这些内存信息保存到hprof文件里面,在使用我 们的第二个工具MAT的时候会使用到这个功能。 2.MAT(Memory Analyzer Tool) Heap工具能给我们一个感性的认识,告诉我们程序当前的内存使用情况和是否存在内存 泄漏的肯能性。但是,如果我们想更详细,更深入的了解内存消耗的情况,找到问题所 在,那么我们还需要一个工具,就是MAT。这个工具是需要我们自己去下载的,可以下 载独立的MAT RCP 客户端,也可以以插件的形式安装到Eclipse里面,方便起见,推荐 后者。 安装方法: A.登录官网https://www.360docs.net/doc/0519204544.html,/mat/downloads.php B.下载MAT Eclipse插件安装包(红框所示,当然你也可是选择Update Site在线安装,个人觉得比较慢)

android内存管理-MAT与防范手段

内存管理与防范手段 目录 内存管理与防范手段 (1) 一.内存分配跟踪工具DDMS–>Allocation tracker 使用 (2) 二.内存监测工具DDMS-->Heap (2) 三.内存分析工具MAT(MemoryAnalyzerTool) (3) 1.生成.hprof文件 (4) 2.使用MAT导入.hprof文件 (5) 3.使用MAT的视图工具分析内存 (5) 四.MAT使用实例 (5) 1.生成heap dump (7) 2.用MAT分析heap dumps (9) 3.使用MAT比较heap dumps (11) 五.防范不良代码 (11) 1.查询数据库没有关闭游标 (11) 2.缓存convertView (12) 3.Bitmap对象释放内存 (13) 4.释放对象的引用 (13) 5.Context的使用 (14) 6.线程 (17) 7.其他 (20) 六.优化代码 (20) 1.使用自身方法(Use Native Methods) (20) 2.使用虚拟优于使用接口 (20) 3.使用静态优于使用虚拟 (20) 4.尽可能避免使用内在的Get、Set方法 (20) 5.缓冲属性调用Cache Field Lookups (21) 6.声明Final常量 (21) 7.慎重使用增强型For循环语句 (22) 8.避免列举类型Avoid Enums (23) 9.通过内联类使用包空间 (23) 10.避免浮点类型的使用 (24) 11.一些标准操作的时间比较 (24) 12.为响应灵敏性设计 (25)

一.内存分配跟踪工具DDMS–>Allocation tracker 使用 运行DDMS,只需简单的选择应用进程并单击Allocation tracker标签,就会打开一个新的窗口,单击“Start Tracing”按钮;然后,让应用运行你想分析的代码。运行完毕后,单击“Get Allocations”按钮,一个已分配对象的列表就会出现第一个表格中。单击第一个表格中的任何一项,在表格二中就会出现导致该内存分配的栈跟踪信息。通过allocation tracker,不仅知道分配了哪类对象,还可以知道在哪个线程、哪个类、哪个文件的哪一行。 尽管在性能关键的代码路径上移除所有的内存分配操作不是必须的,甚至有时候是不可能的,但allocation tracker可以帮你识别代码中的一些重要问题。举例来说,许多应用中发现的一个普遍错误:每次进行绘制都创建一个新的Paint对象。将Paint的创建移到一个实例区域里,是一个能极大提高程序性能的简单举措。 二.内存监测工具DDMS-->Heap 无论怎么小心,想完全避免badcode是不可能的,此时就需要一些工具来帮助我们检查代码中是否存在会造成内存泄漏的地方。Androidtools中的DDMS就带有一个很不错的内存监测工具Heap(这里我使eclipse的ADT插件,并以真机为例,在模拟器中的情况类似)。用Heap 监测应用进程使用内存情况的步骤如下: 1.启动eclipse后,切换到DDMS透视图,并确认Devices视图、Heap视图都是打开的; 2.将手机通过USB链接至电脑,链接时需要确认手机是处于“USB调试”模式,而不是作为“MassStorage”; 3.链接成功后,在DDMS的Devices视图中将会显示手机设备的序列号,以及设备中正在运行的部分进程信息; 4.点击选中想要监测的进程,比如system_process进程; 5.点击选中Devices视图界面中最上方一排图标中的“UpdateHeap”图标; 6.点击Heap视图中的“CauseGC”按钮; 7.此时在Heap视图中就会看到当前选中的进程的内存使用量的详细情况 a)点击“CauseGC”按钮相当于向虚拟机请求了一次gc操作;

Android内存检测

Android 内存检测 1. Introduction Android对内存的使用包括内存泄漏和内存越界,内存泄漏会导致系统内存减少,最终分配不到内存,这样大的程序就不能运行,甚至系统没有内存而崩溃。Android中kernel和应用程序都可能会有内存泄漏和越界。对于Java代码,在越界的时候虚拟机会加以检查并抛出异常。而对于C/C++代码,越界的时候就悄无声息地让程序出错或crash 2. 内核中的内存泄漏检测 内核中已经内嵌了内存泄漏的代码,编译的时候需要打开配置 代码及帮助位置: 其中kmemcheck是检测内存越界等错误的,目前只支持X86 kernel/Documentation/kmemleak.txt kernel/Documentation/kmemcheck.txt kernel/mm/kmemleak.c kernel/mm/kmemcheck.c 内核配置 CONFIG_DEBUG_KMEMLEAK=y CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE=1000 其中CONFIG_DEBUG_KMEMLEAK_EARLY_LOG_SIZE的大小跟board的kernel porting相关, 有的不需要定义,有的需要定义大一点,可以在kmemleak.c中模块初始化代码中调试. kmemleak模块初始化成功后,会产生/sys/kernel/debug/kmemleak这个文件 操作命令如下: #su #echo scan > /sys/kernel/debug/kmemleak扫描泄漏 #cat /sys/kernel/debug/kmemleak 查看泄漏 #echo clear > /sys/kernel/debug/kmemleak清除结果 当出现泄漏后,会有提示,比如 unreferenced object 0xd25f3cc0 (size 64): comm "Binder_5", pid 1257, jiffies 68676 (age 3105.280s) hex dump (first 32 bytes): 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [] create_object+0x12c/0x248 [] kmemleak_alloc+0x88/0xcc [] kmem_cache_alloc_trace+0x13c/0x1f4 [] ion_carveout_heap_map_dma+0x34/0xcc [] ion_alloc+0x170/0x3f0

Android App内存泄露测试方法总结

Android App内存泄露测试方法总结 1、内存泄露 Android系统为每一个运行的程序都指定了一个最大运行内存,超过这个值则会触发OOM机制,反应在界面就是闪退、Crash现象,导致OOM发生的原因比如内存泄露或者是代码不考虑后果使用大量的资源,都有可能导致OOM出现的。OOM的临界值可以通过adb shell getprop | findstr “heap”查看到: 2、Android的GC机制 Android GC机制沿用了java的GC机制,当需要新内存去分配对象的时候而剩余不够的时候,会触发GC,把无用的对象回收掉,其中一个重要的算法便是分代式算法,这个算法把虚拟机分为年轻代、老年代和持久代,对象先分配到年轻代,然后GC多次后还存活的将会移动到老年代,老年代就不会频繁触发GC机制,一般触发频繁的都是年轻代的对象。 3、为什么会内存泄露 上面我们知道了GC机制,那么如果GC过后程序还是没有内存,那么会发生OOM,导致GC后还是没有足够内存分配新对象的主要原因就是内存泄露了。首先要知道内存泄露也就是GC不掉的根源是生命周期长的对象持有生命周期短的对象,导致无用的对象一直无法回收。以下是几个典型的分类: 1)**静态类相关的泄露:**static对象的生命周期伴随着整个程序的生命周期,所以这块要注意不要把一些对象引用添加到static对象里面去,会造成与之关联的对象无法回收。

2)各种资源的释放:包括cursor的关闭,IO流的关闭,bitmap的回收等,进行一些带有缓存的资源一定要关闭或者释放。 3)Handler的泄露:调用handler的delay的时候,会被认为对象是有用的,导致无法回收,还有handler开启线程去下载东西没有下载完成的时候,也会因为线程导致无法回收activity;或者使用handlerThread的时候,有延迟的方法,都会导致无法回收。其主要原因在于handler是持有activity的引用,主线程不是自带一个Looper然后给handler用,导致有关联关系。 4)各种注册引用方法:比如一个常驻的后台线程处理某些时间,把当前对象注册,因为一直持有对象引用,导致这个activity一直保留,所以不用的时候需要反注册。 5)把对象缓存进容器内却忘记remove掉:有时候为了加快页面响应,结果缓存一些对象到容器内,结果越加越多,然后挂掉。 4、系统级别的内存管理 1)LMK机制和oom_adj的值 Android内核有个专用的驱动low-memory-kill,当系统级别的内存不够的时候会根据oom_adj的值以及内存分配状况去kill掉某个进程,oom_adj可以在 /proc/[pid]/oom_adj看到,并且这个值会随着进程的状态改变而改变,比如系统进程一般是-16,越大越容易被干掉。 2)5个进程的优先级 前台进程:当前运行的,基本不死; 可见进程:界面可以见到,比如被遮挡; 服务进程:进程带后台服务的,比如播放器; 后台进程:点击home键,但不退出,就是后台进程了,有比较大几率会被杀;

如何清理释放Android手机内存空间

如何清理释放Android手机内存空间 和PC用户一样智能手机用户也会遇到手机存储不足的问题,对于Android手机来说因为系统不支持安装程序到SD卡,手机配置的存储容量也有限,很多用户都碰到过安装程序太多系统内存不足的问题。虽然Android 2.2系统开始已经支持Apps2SD功能,但是很多用户使用后发现Android 2.2系统下仍然有很多应用程序无法安装到SD卡,即可程序支持移动到SD 卡,但是还会保留一部分系统文件和隐私文件在手机内存里。另外还有一些程序像Widgets,动态壁纸和一些系统程序,如果安装在SD卡根本无法正常工作,内存不足依然是让很多用户感到棘手的问题。 不过Android作为一种优秀的移动操作系统,提供了几种可以清理和释放内存空间的办法,我们总结了下面几点希望可以帮助用户解决燃眉之急。 清理大型应用程序的缓存数据 ●通过清理程序的缓存文件,释放的内存空间会让你喜出望外 ●进入手机设置选项,选择设置>应用程序>管理应用程序 ●按一下Menu键,选择“按大小排序”选项(如果是Android 2.2手机先要选择已下载标 签),然后就可以按照应用程序大小排列所有手机安装的应用程序 ●点击一款列表中的应用程序,如果程序有缓存文件可以显示大小,直接点击“清除缓存” 选项就可以释放这些缓存文件占据的空间 ●有一些应用程序的缓存文件可能多达数MB,比如Google Maps,Market,浏览器和相册 程序,清理这几个程序的缓存文件就可以释放相当可观的空间。 ●很多手机厂商都在旗下手机预装了自己开发的UI程序,比如HTC Sense,MOTOBLUR等, 如果你打算使用LaunherPro或者ADW这样的launcher程序替代HTC Sense,你可以清理甚至删除HTC Sense的数据文件,这个操作可以让你的手机多出几十MB空间。 ●另外Android Market还提供一些自动清除缓存文件的应用程序,比如Quick App Clean Cache这款收费软件。对于已经取得root权限的手机用户,可以从Market下载CacheCleaner, CacheMate和MoveCache这些程序来快速方便的清除程序缓存文件。 删除那些你从来不用或者很少使用的应用程序 这是很多用户都会面对的问题,默默忍受着手机内存不足的报警,甚至牺牲系统性能,就是舍不得删除那些从来不用或者极少使用的应用程序,这可能也是一种强迫症。删除这些程序你会发现手机从此海阔天空,而且你没有任何损失。 移动所以可以移动的应用程序数据到SD

android系统信息(内存、cpu、sd卡、电量、版本)获取

要转载请注明出处:https://www.360docs.net/doc/0519204544.html,/blog/1066113,有很多转载了文章不写出处,还写的是什么小编最近做项目碰到什么问题怎么解决的的然后把文章贴下面,俨然一副他们自己的文章,不知羞耻! 一、内存(ram): android的总内存大小信息存放在系统的/proc/meminfo文件里面,可以通过读取这个文件来获取这些信息: Java代码 1public void getTotalMemory(){ 2String str1="/proc/meminfo"; 3String str2=""; 4try{ 5FileReader fr=new FileReader(str1); 6BufferedReader localBufferedReader=new BufferedReader(fr,8192); 7while((str2= localBufferedReader.readLine())!=null){ 8Log.i(TAG,"---"+str2); 9} 10}catch(IOException e){ 11} 12}

运行信息如下: Java代码 1305-3008:05:14.807:INFO/-SystemInfo-(1519): ---MemTotal:204876kB 1405-3008:05:14.807:INFO/-SystemInfo-(1519):---MemFree: 4596kB 1505-3008:05:14.807:INFO/-SystemInfo-(1519):---Buffers: 16020kB 1605-3008:05:14.807:INFO/-SystemInfo-(1519):---Cached: 82508kB 1705-3008:05:14.807:INFO/-SystemInfo-(1519): ---SwapCached:64kB 1805-3008:05:14.807:INFO/-SystemInfo-(1519):---Active: 137104kB 1905-3008:05:14.807:INFO/-SystemInfo-(1519): ---Inactive:41056kB 2005-3008:05:14.807:INFO/-SystemInfo-(1519): ---SwapTotal:65528kB 2105-3008:05:14.817:INFO/-SystemInfo-(1519): ---SwapFree:65368kB

低端android机内存管理优化

大家好,今天我主要来和大家交流下低端android手机内存优化的问题。 一、问题的引出 前天,我在论坛发了一个帖子,想请教大家关于联想A68e内存优化的问题,但是回复者寥寥无几,课件也很少有机油对这方面有较深入的 学习了解。我今天中午,查了有关资料,也用了自己的手机进行了测试,觉得可能对A68e(其实是广大低端Android手机)用户有点帮助,所以特地来分享以下。(说明:本人用的是Sumsumg I9103,我媳妇用的是电信套餐的联想A68e,这几天我没拿到她的手机来测试,所以只能自己的手机进行测试,但是我觉得还是具有一定的参考价值的)。二、ROM和RAM 首先,我先解释一下ROM和RAM的区别。 ROM是Read Only Memory,即只读存储器;RAM是Access Random Memory,即随即读写存储器。 ROM是存储程序和数据的,类别电脑的硬盘,可以存放安装的程序、文件、数据等。而论坛中有开AppEXT2的方法(我没试过),那个只是节省出更多的ROM空间,这样可以使程序运行得更为流畅,但是不能解决“同时运行程序的数量最大值太小”的问题。以A68e为例,如果开一个QQ、音乐播放器,再开个UC浏览器估计机子就崩溃而导致程序退出。 RAM才是程序运行时所占用的物理空间。RAM的价格比ROM贵很多,所以RAM的大小一半程度上决定了机子的价位(另一半就是CPU)。

我的Sumsung是1G RAM,同时开QQ、QQ游戏、QQ音乐、浏览器、微信等七、八个程序也毫无压力。所以RAM太小是影响A68e(包括很多Android手机)用户体验的原因。如果你是个游戏玩家、手机达人,那么这类机子一定不适合你。如果你希望能像有高端机那样的用户体验,我建议你还是多话点银子购买配置高的Android手机。 关于官方宣传256的RAM实际上只有170,那是有一部分被Android系统占用。我的手机1GRAM,实际上也只有724M。 三、Android系统内存管理机制及进程调度机制 下面开始具体的分析了。 首先Android系统是基于Linux 内核开发的开源操作系统,li nux系统的内存管理有其独特的动态存储管理机制。Android采取了一种有别于Linux的进程管理策略,Linux系统在进程活动停止后就结束该进程,而Android把这些进程都保留在内存中,直到系统需要更多内存为止。这些保留在内存中的进程通常情况下不会影响整体系统的运行速度,并且当用户再次激活这些进程时,提升了进程的启动速度。 Android系统这样的设计不仅非常适合移动终端(手机、平板)的需要,而且减少了系统崩溃的可能,确保了系统的稳定性。老想着清理内存的同学完全是因为被塞班或者Windows毒害太深,事实上,经常用Taskiller之类的软件关闭后台所有进程,很容易造成系统的不稳定。很多时候出现问题了,只要重启就能解决的原因也在于此。 广大机油一定会发现,关闭了QQ、微信等程序后,其实并没有完全关闭这些程序。这些程序在后台占用了一定的内存,但是并没有运行时

安卓系统手机内存空间不足的清理方法

安卓系统手机内存空间不足的清理方法 然后很多手机都有将app安装到内存卡的功能,所以除了必须 安装在手机内存的软件之外,可以把软件都安装到sd卡中节省手机 内存。下面是jy135收集的安卓系统手机内存空间不足的清理方法,欢迎阅读。 清理大型应用程序的缓存数据 通过清理程序的缓存文件,释放的内存空间会让你喜出望外 进入手机设置选项,选择设置>应用程序 >管理应用程序 按一下Menu键,选择“按大小排序”选项(如果是Android 2.2手机先要选择已下载标签),然后就可以按照应用程序大小排列所有 手机安装的应用程序 点击一款列表中的应用程序,如果程序有缓存文件可以显示大小,直接点击“清除缓存”选项就可以释放这些缓存文件占据的空间有一些应用程序的缓存文件可能多达数MB,比如Google Maps,Market,浏览器和相册程序,清理这几个程序的缓存文件就可以释放 相当可观的空间。 很多手机厂商都在旗下手机预装了自己开发的UI程序,比如HTC Sense,MOTOBLUR等,如果你打算使用LaunherPro或者ADW这样的launcher程序替代HTC Sense,你可以清理甚至删除HTC Sense 的数据文件,这个操作可以让你的手机多出几十MB空间。 另外Android Market还提供一些自动清除缓存文件的应用程序,比如Quick App Clean Cache这款收费软件。对于已经取得root权

限的手机用户,可以从Market下载 CacheCleaner, CacheMate和MoveCache这些程序来快速方便的清除程序缓存文件。 删除那些你从来不用或者很少使用的应用程序 这是很多用户都会面对的问题,默默忍受着手机内存不足的报警,甚至牺牲系统性能,就是舍不得删除那些从来不用或者极少使用的应用程序,这可能也是一种强迫症。删除这些程序你会发现手机从此海阔天空,而且你没有任何损失。 移动所以可以移动的应用程序数据到SD卡 运行Android 2.2系统的手机支持安装应用程序到SD卡,确保检查所有你安装的应用程序如果支持apps to SD卡功能一定要移动到SD卡,对于一些大型软件特别是游戏程序节省的容量相当可观。不过一定要注意Widgets程序,捆绑Widgets的程序,以及动态壁纸程序和那些需要在后台运行并且和系统进行交互的应用程序不要移 动到SD卡存储,否则程序可能无法正常工作。 如果觉得每个程序单独设置太麻烦,可以借助Apps 2 SD和SDMove这样的程序简化操作过程。对于那些动手能力比较强的用户可以通过网上的教程设置应用程序默认安装到SD卡,这样就可以一劳永逸。 如果我们感觉到我们的手机由于内存过多,影响到我们手机的正常使用,可以进入到手机的相关设置中,找到通用按钮点击进入。 2 进入到手机的通用界面中后,我们可以看到手机中的相关系统空间状况,点击查看相应的手机存储详情。

Android中内存优化

Android中内存优化的那些事一个有关图片的优化记录 客服群里叫喊着:这个用户图片不显示了,那个用户图片也不显示了。我拿着手上一切正常的测试机,what the hell…… 默默地打开bugly。 满园春色关不住,遍地内存溢出来!是的,又闯祸了! 内存问题永远是既陌生又熟悉的话题,而且大多数都发生在一个叫作用户家的手机上。安卓系统本身不断的在优化,三方框架也逐渐成熟,外加手机厂商的大内存加持,似乎内存问题变得少见,但还是不能忽视。 借着这次修复内存问题的记录,分享一些“自以为”的解决思路,仅供参考。ok,let’s go! 修复问题的三部曲,先复现,再定位,最后修复。 复现 估计有的人会说,异常现象都在那,有啥好复现的,冲进代码直接开干。 修复bug永远是个惊心动魄的事,稍微一不小心就有可能天崩地裂。不是修复不完全,就是引入新问题。从起因开始了解整个缘由,一方面能加深对问题的理解,同时确保最终能验证问题是否得到修复。 内存的问题经常发生在一些比较特殊的环境下,而且很多时候不一定是必现,往往体现在一些中低端机型上。所以从机型上入手可能会是一个不错的选择。 最终,通过bugly查到了对应的问题机型及系统版本,上各类云测平台找到了台云测试机。按照进入问题页面的几个固定流程,反复执行,最终锁定了复现流程。

定位 知道问题如何复现,接下来就是定位问题到底出在哪。通常内存的问题,会碰到两种情况: 1.内存堆积:由于特殊情况造成的页面关闭但资源还遗漏在内存中。 2.内存高占用:由于业务需要或者使用不当导致内存占用量过高。 我们先来看看这次的问题属于哪种情况。 在Android Studio2.3及之前版本上自带的Android monitor中,可以直观的反应出当前应用的整体内存使用水平。[如何使用工具的分享估计大家都看腻了,这次就不再重复了。 142MB!!!!进入事故现场之前就已经被占用了这么多内存。难怪之后会内存异常。看来这次要先解决内存高占用的问题,我们先要详细的了解内存的具体情况,才知道从哪下手去解决,无论是避免无意义的使用或者优化必要的占用。 先强制gc一下,然后dump java heap,看一下整体内存里的情况,按照shallow size排序。 首当其冲的byte数组映入眼帘,大家都明白的,bitmap一直都是大客户。我们接着分析下byte[]中的各个对象。

Android内存使用研究

Android 内存使用研究 众所周知,在写 android 程序的时候,很容易出现 OOM ,而出现的时机大多数是由 Bitmap decode 引发的: 1 ERROR/AndroidRuntime(16350): https://www.360docs.net/doc/0519204544.html,ng.OutOfMemoryError: bitmap size exceeds VM budget 我们知道,android 程序内存一般限制在16M ,当然也有24M 的,而android 程序内存被分为2部分:native 和dalvik : dalvik 就是我们平常说的java 堆,我们创建的对象是在这里面分配的,而bitmap 是直接在native 上分配的,对于内存的限制是native+dalvik 不能超过最大限制。 注:一旦内存分配给Java 后,以后这块内存纵然开释后,也只能给Java 的施用,这个估计跟java 虚拟机里把内存分成好几块进行缓存的原因有关,反正C 就别想用到这块的内存了,所以要是Java 突然占用了一个大块内存,纵然很快开释了: C 能施用的内存 = 16M - Java 某一瞬间占用的最大内存。 而Bitmap 的生成是通过malloc 进行内存分配的,占用的是C 的内存,这个也就说明了,上面所说的的4MBitmap 无法生成的原因,因为在13M 被Java 用过后,剩下C 能用的只有3M 了。 用以下命令可以查看程序的内存使用情况: adb shell dumpsysmeminfopackagename orpid 程序的包名或者进程id

其中size是需要的内存,而allocated是分配了的内存,对应的2列分别是native和dalvik,当总数也就是total这一列超过单个程序内存的最大限制时,OOM就很有可能会出现了。 多数时候,发生OOM 都是在做一些跟图片相关的操作,以下提出一些建议尽量可以减少这种情况的发生: 1 .decode bitmap 的时候,尽量配置下Options,例如:inSameSize 2 .Bitmap使用完以后,调用 bitmap.recycle()来释放内存 3 .如果应用是基于图片的应用,尽量采用LazyLoad和DymanicRecycle 4.decode bitmap 的时候,将decode代码 try catch 出来,catch oom error,避免程序crash,可以在catch里面做一些释放内存操作 关于Android的Native内存和Dalvik内存 1.Dalvik内存 每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。 很多人认为Dalvik虚拟机是一个Java虚拟机,因为Android的编程语言恰恰就是Java语言。但是这种说法并不准确,因为 Dalvik虚拟机并不是按照Java 虚拟机的规范来实现的,两者并不兼容; 同时还要两个明显的不同: 1.Java虚拟机运行的是Java字节码,而Dalvik虚拟机运行的则是其专有的文件格式DEX(Dalvik Executable)。 2.在Java SE程序中的Java类会被编译成一个或者多个字节码文件(.class)然后打包到JAR文件,而后Java虚拟机会从相应的CLASS文件和JAR文件中获取相应的字节码;Android应用虽然也是使用Java语言进行编程,但是在编译成CLASS文件后,还会通过一个工具(dx)将应用所有的 CLASS文件转换成一个DEX文件,而后Dalvik虚拟机会从其中读取指令和数据。 Dalvik虚拟机的简介: Dalvik虚拟机主要是完成对象生命周期的管理,堆栈的管理,线程管理,安全和异常的管理,以及垃圾回收等等重要功能。 Dalvik虚拟机的主要特征Dalvik虚拟机非常适合在移动终端上使用,相对于在桌面系统和服务器系统运行的虚拟机而言,它不需要很快的CPU速度和大量的内存空间。 Dalvik虚拟机有如下几个主要特征: 1.专有的DEX文件格式 DEX是Dalvik虚拟机专用的文件格式,而问什么弃用已有的字节码文件(CLASS文件)而采用新的格式呢?一个应用中会定义很多类,编译完成后即会有很多相应的CLASS 文件,CLASS文件间会有不少冗余的信息;而DEX文件格式会把所有的CLASS文件内容整合到一个文件中。这样,除了减少整体的文件尺寸,I/O操作,也提高了类的查找速度。 2.增加了新的操作码的支

相关文档
最新文档