zoukankan      html  css  js  c++  java
  • 浅谈Android应用性能之内存


                                  本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!


    文/ 


    [博主导读]在Android开发中,不免会遇到许多OOM现象,一方面可能是由于开发者能力有限,对控件使用不熟悉,另一方面架构师前期未未做及时培训,规避一些恶性代码、及时手动回收内存。不管怎样,项目完成还是要发布的,周期有限,后期优化工程师为解决此问题,则需要对项目整体进行把握,从微调开始,对项目进行手术。那么切入正题:



    如何测试一个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掉我们要尽可能的合理使用内存避免内存泄漏的情况发生。


    转自:http://blogs.360.cn/blog/浅谈android应用性能之内存/

  • 相关阅读:
    POJ 3268 Silver Cow Party (Dijkstra)
    怒学三算法 POJ 2387 Til the Cows Come Home (Bellman_Ford || Dijkstra || SPFA)
    CF Amr and Music (贪心)
    CF Amr and Pins (数学)
    POJ 3253 Fence Repair (贪心)
    POJ 3069 Saruman's Army(贪心)
    POJ 3617 Best Cow Line (贪心)
    CF Anya and Ghosts (贪心)
    CF Fox And Names (拓扑排序)
    mysql8.0的新特性
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147375.html
Copyright © 2011-2022 走看看