zoukankan      html  css  js  c++  java
  • 浅谈android应用性能之内存(转)

    如何测试一个APP的内存占用情况?一个APP占用的内存分哪些部分?如何检查一个APP是否存在内存泄漏?

    一、Android内存介绍:

    在java开发过程中,是通过new来为对象分配内存的,而内存的释放是由垃圾收集器(GC)来回收的,在开发的过程中,不需要显式的去管理内存,java虚拟机会自动帮我们回收内存。但是这样有可能在不知不觉中就会浪费了很多内存,最终导致java虚拟机花费很多时间去进行垃圾回收,更严重的是造成JVM的OOM。

    二、APP占用的内存分哪些

    Android系统中的内存和linux系统一样,存在着大量的共享内存。每个APP占内存会有私有和公共的两部分:ShareDirty、PrivateDirty。Pss是考虑共享内存的内核计算尺度 — 基本上一个进程的每个内存页面被按一个比率缩减,这个比率和同样使用该页面的其他进程的数量有关。理论上你可以累计所有进程的Pss占用量来检查所有进程的内存占用量,也可以比较进程的Pss来大致发现进程各自的权重。PrivateDirty,它基本上是进程内不能被分页到磁盘的内存,也不和其他进程共享。

    手机中系统设置里有可以查看正在运行的应用程序所占的内存,此处显示的内存为该进程所占用的Total Pss。所以我们只需要查看Total Pss的值就可以知道该应用运行时所占的内存的大小。

    三、如何查看一个APP占用的内存

    查看内存大致上有三种方法:

    1. 通过系统设置查看

    在系统设置中->应用->正在运行->APP

    优点:操作简单

    缺点:数值不准确,无法实时查看数值变化

    2. 通过命令行查看

    adb shell dumpsys meminfo yourpakagename

    结果如下图所示

    1

    其中Pss对应的TOTAL值为内存所实际占用的值

    优点:简单方便,数据全面精确

    缺点:无法实时查看内存占用

    3. 通过系统API查看

    首先通过activitymanager获得正在运行的程序列表,找到所要获取的程序的pid。

    activitymanager.getRunningAppProcesses()

    再通过memoryinfo[0].getTotalPss();方法获得实际内存占用

    Memoryinfo中还包括getTotalPrivateDirty和getTotalSharedDirty方法

    优点:可拓展性高,可以通过程序实时查看内存的占用;数据全面精确

    缺点:需要具有开发能力,入手较为困难

    所以我们现在在测试内存的时候,是使用了内部自己研发的一款APP来监测内存的,这个APP目前可以实现实时监测并记录数据结果,可以提供给开发者和测试者分析内存的数据支持。目前仍然属于内测阶段,以后有机会可以提供给大家使用。

    四、内存泄漏

    何为内存泄漏?内存泄漏也称作“存储渗漏”,用动态存储分配函数动态开辟的空间,在使用完毕后未释放,结果导致一直占据该内存单元,直到程序结束。

    内存泄漏的实例:

    btn.setOnClickListener(new OnClickListener() {

    @Override

    public void onClick(View arg0) {

    for (int i = 0; i < 100; i++) {

    ImageView img = new ImageView(MainActivity.this);

    img.setImageResource(R.drawable.ic_launcher);

    test.add(img);

    }

    }

    });

    其中test为静态的List<ImageView>。

    这样,如果一直点击btn就会出现内存泄漏的情形。

    我们如何去监测内存泄漏呢?

    例:

    以上面内存泄漏的例子为测试Activity,当点击按钮后,会向一个静态数组中添加图片,这样就形成了一个内存泄漏的场景。

    进入测试Activity,在点击按钮前先记录当前APP所占用的内存,然后点击按钮。等待操作执行完成后,进行一次GC,再查看APP所占用的内存。

    返回后APP所占用的内存没有明显的回落,表明在代码中可能存在内存泄漏的情况发生。

    即:在执行某种操作后进行一次GC,内存没有明显的回落。此时即可以断定代码中可能存在内存泄漏。

    检测方法:

    1. 通过上文所用的三种方法去查看内存的使用情况
    2. 使用DDMS中的Heap:

    1)      打开DDMS并打开Devices视图和Heap视图

    2)      点击选择要监控的进程

    3)      选中Devices视图界面上的”update heap” 图标

    4)      点击Heap视图中的”Cause GC” 按钮(相当于进行了一次GC的操作)

    一般我们会观察Data Object的Total值,正常情况下在每次GC后,这个值都会有明显的回落并会稳定在一个范围之内,说明代码中没有未被释放的内存;若这个值在每次GC后没有出现明显的回落,则说明代码中可能存在没有被释放的内存。

    总述:内存不仅是性能测试时需要关注的,作为优秀的开发工程师更应该关注自己的代码内存占用的情况,这样可以尽量避免OoM的情况发生。要知道手机分配给每个进程的内存并不多,当系统内存不够的时候会kill掉一些占内存高的进程,所以为了不被系统kill掉我们要尽可能的合理使用内存避免内存泄漏的情况发生。

  • 相关阅读:
    android提供ToolBar实现划动菜单的陷阱
    style="display"之后不能获取offsetHeight或clientWidth这类测量的值
    onmouseenter与onmouseover
    使用Dom的Range对象处理chrome和IE文本光标位置
    js严格模式“use strict”
    正则表达式lastIndex属性浅析
    IE中的fireEvent和webkit中的dispatchEvent
    readonly=“readonly”与readonly=“true”
    【杂文】
    【洛谷p1015】【一本通p1309】回文数(noip1999)
  • 原文地址:https://www.cnblogs.com/yanghj010/p/4670875.html
Copyright © 2011-2022 走看看