Android内存详解——内存使用情况

来源:互联网 发布:淘宝怎么看上下架时间 编辑:程序博客网 时间:2024/05/24 05:07

Process Stats: Android 4.4 KitKat 提出了一个新系统服务,叫做procstats。它将帮助你更好的理解你app在后台(background)时的内存使用情况。Procstats可以去监视你app在一段时间的行为,包括在后台运行了多久,并在此段时间使用了多少内存。从而帮助你快速的找到应用中不效率和不规范的地方去避免影响其performs,尤其是在低内存的设备上运行时。D:\workspace\android-sdk\platform-tools> adb dumpsys procstats指令是Process Stats的底层实现。你可以通过adb shell dumpsys procstats –hours 3,或者更方便的方式是运行Process Stats开发者工具(在4.4版本的手机中点击Settings > Developer options > Process Stats)
这里写图片描述
上图的左侧为5.0系统,右侧为4.4系统。其中含有在后台运行的总时间,当前内存的状态,百分数表示:当前进程在后台运行时间占总运行时间的百分比,蓝色进度条表示的是每个进程加载的相对消耗内存,单机每个条目可进入详情。
Meminfo:它是根据PSS标准(Proportional Set Size——实际物理内存)计算每个进程的内存使用并且按照重要程度排序。可以通过通过Apps-Running的底层实现的命令,即在目录D:\workspace\android-sdk\platform-tools> adb dumpsys meminfo即可查看当前的实际物理内存,通过多次让APP启动和提出,观察上面命令中显示的Activitys以及Views是否在退出时清零可以初步判断内存是否泄露。此方法查看的内存与Debug.MemoryInfo相同,取出的值包含如下:
dalvikPrivateDirty: The private dirty pages used by dalvik。
dalvikPss :The proportional set size for dalvik.
dalvikSharedDirty :The shared dirty pages used by dalvik.
nativePrivateDirty :The private dirty pages used by the native heap.
nativePss :The proportional set size for the native heap.
nativeSharedDirty :The shared dirty pages used by the native heap.
otherPrivateDirty :The private dirty pages used by everything else.
otherPss :The proportional set size for everything else.
otherSharedDirty :The shared dirty pages used by everything else.
部分含义如下:
(1) PrivateDirty:它是指非共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使你的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已。
(2)SharedDirty:参照PrivateDirty我认为它应该是指共享的,又不能换页出去(can not be paged to disk )的内存的大小。比如Linux为了提高分配内存速度而缓冲的小对象,即使所有共享它的进程结束,该内存也不会释放掉,它只是又重新回到缓冲中而已。
也可以使用在设备上点击Settings > Apps > Running(与Procstats不同,它也可以在老版本上运行)
这里写图片描述
堆内存:在程序中可以使用如下命令查询内存使用情况:
一、ActivityManager.MemoryInfo包含以下集中数据:
(1)totalMem:系统可用的总内存。(2)availMem:系统当前剩余内存。(3)是否处于低内存状态。(4)threshold:内存阈值(5)hreshold:它表示当系统剩余内存低于好多时就看成低内存运行
另外还可以获得getLargeMemoryClass系统的最大可分配内存即OOM的上限,这些值实在系统ROM中,编译时就已经写入系统了,可通过adb shell getprop|grep dalvik.vm.heapgrowthlimit,那么如何来增加系统分配的最大内存呢?一般有如下三种方式:
(1)清单中设置largeheap为true,但是一般不建议如此做,会减慢GC的速度,降低流畅度。
(2)设置android:process子进程,app默认运行在同一个进程中,app如果设置多个子进程,也会产生更多的系统开销和跨进程调用。在android中webview经常用到子进程,由于webview的内存回收很麻烦,经常会存在内存泄露的情况(后面的文章会对webview进行分析)所以普遍会将其设置在单独子进程中,并通过kill process方式来回收。
(3)使用Naive heap:android系统限制的是Java Heap的大小,native heap是由系统分配的,通过jni可以实现对native heap的申请,已知的Fresco就是通过在Native heap上进行内存分配来减少Java heap的内存大小,进而避免因图像占用内存过多而引发的OOM问题。
(4)使用OpenGL:它的很多API都是将RAM作为显存使用,而不受Java heap的限制,进而避免OOM的问题。
Runtime可以获取很多运行时的内存数据:
(1)totalMemory:VM Heap Size
(2)freeMemory:Free VM Heap Size
(3)maxMemory:VM Heap Size Limit
对于APP开发者来说VM Heap Size以及Allocated(VM Heap Size - Free VM Heap Size)最为有用,也是AS Monitor中的内存曲线图。由于Dalvik和ART虚拟机在Pss内存分配上的巨大差异,建议使用Runtime类来分析内存信息。
二、Debug.MemoryInfo memoryInfo,(前面已介绍)
三、android.os.Debug#getNativeHeapSize()返回的是当前进程navtive堆本身总的内存大小android.os.Debug#getNativeHeapAllocatedSize()返回的是当前进程navtive堆中已使用的内存大小android.os.Debug#getNativeHeapFreeSize()返回的是当前进程navtive堆中已经剩余的内存大小。
整个App的内存都是由系统统一管理的,当内存不足时,Android系统就会触发LMK(Low memory kill),杀死一些优先级低的进程。系统在管理内存时,会给Application、Activity、Service等反馈,例如当内存告警时,Application等组件可以监听到LMK发出的onLowMemory()和onTrimMemory等回调。我们可以通过registerComponentCallBacks来监听onLowMemory,触发onLowMemory时,所有的Background进程都已经被杀死了。onTrimMemory在进行时和按home键应用退到后台时,都有各自的三级警告,具体信息读者可以参考http://blog.csdn.net/linghu_java/article/details/17348539,
http://www.cnblogs.com/xiajf/p/3993599.html,这里尤其要提及TRIM_MEMORY_UI_HIDDEN,可以针对此回调做一些UI特定资源的释放。

1 0
原创粉丝点击