zoukankan      html  css  js  c++  java
  • android内存泄漏测试

    要测内存泄漏呢,可以反复进入某一项操作,如反复进入联系人详情后返回键,观察内存的值是否有上升的趋势。

    测试方法:

    1.创建自动化测试脚本,每操作一次获取一次内存值,然后把内存值导出到文件中,制作成曲线图,就可以很直观的看见是否存在内存泄漏了。曾经用Uiautomator做过一次内存泄漏的脚本,如下:

    package demotest;
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.text.SimpleDateFormat;
    import java.util.Arrays;
    import java.util.Date;
    
    import com.android.uiautomator.core.UiObject;
    import com.android.uiautomator.core.UiObjectNotFoundException;
    import com.android.uiautomator.core.UiScrollable;
    import com.android.uiautomator.core.UiSelector;
    import com.android.uiautomator.testrunner.UiAutomatorTestCase;
    
    public class MemoryLeak extends UiAutomatorTestCase {
        // 应用包名
        static final String packageName = "com.android.phone";
    
        // 测试次数
        static final int counts = 500;
        public static void main(String[] args) {
            String jarName, testClass, testName, androidId;
            jarName = "demotest";
            testClass = "demotest.MemoryLeak";
            testName = "testScene_03";
            androidId = "3";
            new UiAutomatorHelper(jarName, testClass, testName, androidId);
            
        }
    
    
    
         // 场景一:打开/退出联系人
         
        public void testScene_01() throws IOException {
            File mTxt = mkFile("01");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            for (int i = 0; i < counts; i++) {
                scene_01();// 执行场景一的case
                sleep(2000);// 延迟2s
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);
            }
            fos.close();
        }
        
        //场景二:查看联系人
        public void testScene_02() throws IOException
        {
            File mTxt = mkFile("02");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_01();//打开联系人
            for(int i=0;i<counts;i++)
            {  
                getUiDevice().click(334, 416);
                sleep(1000);
                getUiDevice().pressBack();
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);
            }
            
            fos.close();
            getUiDevice().pressBack(); // 退出联系人
        }
        
       //添加联系人
        public void testScene_03() throws IOException, UiObjectNotFoundException
        {
            File mTxt = mkFile("03");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_01();//打开联系人
            for(int i=0;i<counts;i++)
            { 
                UiObject add=new UiObject(new UiSelector().resourceId("com.aurora:id/aurora_action_bar_item"));
                add.clickAndWaitForNewWindow();
                UiObject name=new UiObject(new UiSelector().text("请输入姓名"));
                name.setText("penghong");
                sleep(500);
                UiObject number=new UiObject(new UiSelector().text("请输入号码"));
                number.setText("15079034630");
                sleep(1000);
                new UiObject(new UiSelector().text("确定")).clickAndWaitForNewWindow();
                getUiDevice().pressBack(); 
                sleep(2000);// 延迟2s
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);            
            }
            fos.close();
            getUiDevice().pressBack();
            getUiDevice().pressBack();
        }
        //删除联系人
        public void testScene_04() throws IOException, UiObjectNotFoundException
        {
            File mTxt = mkFile("04");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_01();//打开联系人
            for(int i=0;i<counts;i++)
            {
                getUiDevice().swipe(550,395,215,402,40);
                sleep(1000);
                new UiObject(new UiSelector().resourceId("com.aurora:id/aurora_rubbish")).clickAndWaitForNewWindow();
                new UiObject(new UiSelector().text("确定")).clickAndWaitForNewWindow();
                sleep(500);
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);        
            }
            fos.close();
            getUiDevice().pressBack();
        }
        
        
         // 场景一:打开/退出拨号盘
         
        public void testScene_05() throws IOException {
            File mTxt = mkFile("05");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            for (int i = 0; i < counts; i++) {
                scene_001();
                sleep(2000);// 延迟2s
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);
            }
            fos.close();
        }
        
        //拨号盘中界面切换
        public void testScene_06() throws IOException
        {
            File mTxt = mkFile("06");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_001();
            for(int i=0;i<counts;i++)
            {
                getUiDevice().click(134, 1230);
                sleep(500);
                getUiDevice().click(373, 1248);
                sleep(500);
                getUiDevice().click(630, 1250);
                sleep(500);
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);        
            }
            fos.close();
            getUiDevice().pressBack();
        }
        //反复进入电话帮
        public void testScene_07() throws IOException
        {
            File mTxt = mkFile("07");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_001();
            for(int i=0;i<counts;i++)
            {
                getUiDevice().click(373, 1248);
                sleep(500);
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);    
            }
            fos.close();
            getUiDevice().pressBack();
        }
        
        //拨号盘搜索联系人
        public void testScene_08() throws IOException, UiObjectNotFoundException
        {
            File mTxt = mkFile("08");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_001();
            getUiDevice().click(386, 1223);
            sleep(500);
            if(new UiObject(new UiSelector().resourceId("com.android.contacts:id/yulore_superyellowpage_et_search")).exists())
            {
                getUiDevice().click(386, 1223);
                sleep(500);
            }
            for(int i=0;i<counts;i++)
            {
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_one")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_three")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_zero")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_deleteButton")).longClick();
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);    
            }
            fos.close();
            getUiDevice().pressBack();
        }
        
        
        //拨号盘呼叫
        public void testScene_09() throws IOException, UiObjectNotFoundException
        {
            File mTxt = mkFile("09");// 创建文件
            FileOutputStream fos = null;// 以字节流的形式读取
            fos = new FileOutputStream(mTxt);
            scene_001();
            getUiDevice().click(386, 1223);
            sleep(500);
            if(new UiObject(new UiSelector().resourceId("com.android.contacts:id/yulore_superyellowpage_et_search")).exists())
            {
                getUiDevice().click(386, 1223);
                sleep(500);
            }
            for(int i=0;i<counts;i++)
            {
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_one")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_zero")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_zero")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_eight")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_six")).click();
                new UiObject(new UiSelector().resourceId("com.android.contacts:id/aurora_dialButton")).click();
                sleep(3000);
                new UiObject(new UiSelector().text("结束通话")).clickAndWaitForNewWindow();
                String mMemory = memory(packageName);// 读取每一次的memory
                sleep(2000);
                byte[] b1 = (mMemory + "
    ").getBytes();
                fos.write(b1);    
            }
            fos.close();
            getUiDevice().pressBack();
        }
        
        
        //打开联系人
        public void scene_01() {
            getUiDevice().pressHome();
            UiScrollable deckViews = new UiScrollable(
                    new UiSelector().scrollable(true));
            deckViews.setAsHorizontalList();
            UiObject sApp;
            try {
                sApp = deckViews
                        .getChildByText(
                                new UiSelector()
                                        .className(android.widget.TextView.class
                                                .getName()), "联系人");
                sApp.clickAndWaitForNewWindow();
            } catch (UiObjectNotFoundException e) {
                e.printStackTrace();
            }
            //getUiDevice().pressBack();
        }
    
        //打开拨号盘
        public void scene_001() {
            getUiDevice().pressHome();
            UiScrollable deckViews = new UiScrollable(
                    new UiSelector().scrollable(true));
            deckViews.setAsHorizontalList();
            UiObject sApp;
            try {
                sApp = deckViews
                        .getChildByText(
                                new UiSelector()
                                        .className(android.widget.TextView.class
                                                .getName()), "拨号");
                sApp.clickAndWaitForNewWindow();
            } catch (UiObjectNotFoundException e) {
                e.printStackTrace();
            }
            //getUiDevice().pressBack();
        }
    
    
        
    
        // 读取每一次的内存值
        public String memory(String packageName) {
            Process proc = null;
            StringBuffer sb = new StringBuffer();
            String line, Pss = null;
            try {
                proc = Runtime.getRuntime().exec("dumpsys meminfo " + packageName);
                proc.waitFor();
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        proc.getInputStream()));
                while ((line = br.readLine()) != null) {
                    if (line.contains("TOTAL")) {
                        sb.append(line + "
    ");
                    }
                }
                String[] s = sb.toString().split("TOTAL");
                String s2 = s[1].trim();
                String[] s3 = s2.split("    ");
                Pss = s3[0].trim();
                System.out.println("***调试开始***");
                System.out.println(sb.toString());// 打印字符串
                System.out.println(Arrays.toString(s));// 打印数组
                System.out.println(s2);
                System.out.println(Arrays.toString(s3));
                System.out.println("Pss=" + Pss);
                System.out.println("***调试完成***");
            } catch (IOException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return Pss;
        }
    
        // 格式化时间
        public String formatDate() {
            Date date = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHms");
            String time = sdf.format(date);
            return time;
        }
    
        // 创建文件保存日志
        public File mkFile(String casename) {
            String path = "/storage/sdcard0/uiautomator/memory";
            String file = path + "/Scene_"+casename + formatDate() + ".log";
            File filePath = new File(path);
            File txt = new File(file);
            if (!filePath.exists() && !txt.exists()) {
                filePath.mkdirs();
                try {
                    txt.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return txt;
        }
    
    }

    2.用 bat脚本连续读取应用程序的内存使用情况(一边操作一边观察内存值是否一直上升)

    set process=com.android.contacts
    @adb shell dumpsys meminfo %process% | findstr "Pss"
    :m
    @adb shell dumpsys meminfo %process% | findstr "TOTAL"
    @ping -n 5 127.1>nul
    @goto m

    3.用eclipse中的DDMS

    手动连电脑,选中要测试的进程名--点击Update heap--操作应用的同时观察右边Heap区域的total size是否会一直上升,在此期间可以点击GC按扭触发android垃圾回收

    如果一直呈上升趋势则点击Dump HPROF按扭把内存映像拷贝下来,然后用MAT工具去分析。

    上面这命令也可以获取HPROF文件

  • 相关阅读:
    [LOJ 6436][PKUSC2018] 神仙的游戏
    [BZOJ 2653] middle
    [WC2018] 州区划分
    [BZOJ 4556][Tjoi2016&Heoi2016]字符串
    [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)
    [BZOJ 4573][ZJOI 2016]大♂森林
    Problem 2322. -- [BeiJing2011]梦想封印
    [BZOJ 2555] SubString
    [日常] NOIWC2019 冬眠记
    [BZOJ 4036][HAOI2015]按位或
  • 原文地址:https://www.cnblogs.com/penghong2014/p/4914787.html
Copyright © 2011-2022 走看看