安卓专项测试之内存及PerfDog和SoloPi比较

这次继续安卓专项测试之内存

Android系统中每个APP占内存会有私有和公共的两部分:ShareDirty、PrivateDirty。“PrivateDirty”内存是其最重要的部分,因为只被自己的进程使用。它只在内存中存储,因此不能做分页存储到外存(Android不支持swap)。所有分配的Dalvik堆和本地堆都是“private dirty”内存;Dalvik堆和本地堆中和Zygote进程共享的部分是共享dirty内存。
而Pss是另一种应用内存使用的计算方式,是把跨进程的共享页也计算在内 — 例如,在两个进程间共享的页,计算进每个进程PPS的值是它的一半大小。PSS计算方式的一个好处是:把所有进程的PSS值加起来就可以确定所有进程总共占用的内存。这意味着用PSS来计算进程的实际内存使用、进程间对比内存使用和总共剩余内存大小是很好的方式。
通常来说,我们只需关心Pss Total列和Private Dirty列就可以了
Android里最常用于观察进程内存的方法就是dumpsys meminfo 命令,如下图:
安卓专项测试之内存及PerfDog和SoloPi比较_第1张图片

SoloPi与PerfDog测试结果对比:

测试过程为打开app,然后进入游戏,玩一局,退出(重复三次),退出数据监控

PerfDog测试结果:
安卓专项测试之内存及PerfDog和SoloPi比较_第2张图片

SoloPi 测试结果(监控间隔为500ms)
安卓专项测试之内存及PerfDog和SoloPi比较_第3张图片
(不知道为什么SoloPi的PSS内存,PrivateDirty内存数据 都为0)
安卓专项测试之内存及PerfDog和SoloPi比较_第4张图片
安卓专项测试之内存及PerfDog和SoloPi比较_第5张图片

PerfDog 图比较直观,很容易看出app内存存在异常,一直在增加,SoloPi全局占用也能看出内存不断增加,PerfDog增加幅度为80M,50M,53M,SoloPi全局占用内存增加幅度35M,48M,62M

SoloPi代码分析(PerfDog没有开源):

用SoloPi测试app性能,有关内存方面,会生成全局占用,PSS内存,PrivateDirty内存三个文件
全局占用 = totalMemory - getAvailMemory;

RecordPattern pattern = new RecordPattern("全局占用", "MB", "Memory");
		pattern.setStartTime(startTime);
		pattern.setEndTime(endTime);
		result.put(pattern, usedMemory);

usedMemory 在totalMemory - getAvailMemory(context)里面获取

usedMemory.add(new RecordPattern.RecordItem(System.currentTimeMillis(), (float)(totalMemory - getAvailMemory(context)), ""));

totalMemory ----> totalMemory = getTotalMemory()

/**
	 * 获取总内存数据
	 * @return
	 */
	private Long getTotalMemory() {
		if (activityManager == null) {
			return 0L;
		}

		MemoryInfo info = new MemoryInfo();

		activityManager.getMemoryInfo(info);

		return info.totalMem / BYTES_PER_MEGA;
	}
public static Long getAvailMemory(Context cx) {// 获取android当前可用内存大小
		if (cx == null) {
			return 0L;
		}

		ActivityManager am = (ActivityManager) cx.getSystemService(Context.ACTIVITY_SERVICE);
		MemoryInfo mi = new MemoryInfo();
		am.getMemoryInfo(mi);
		LogUtil.i(TAG, "Available memory: " + mi.availMem);
		// mi.availMem; 当前系统的可用内存

		return mi.availMem / BYTES_PER_MEGA;// 将获取的内存大小规格化
	}

PSS内存,PrivateDirty内存计算如下:

// 对每个进程的数据都进行记录

ArrayList<RecordPattern.RecordItem>[] pidRecord = appMemory.get(pid);

			pattern = new RecordPattern("PSS内存-" + pid, "MB", "Memory");
			pattern.setStartTime(startTime);
			pattern.setEndTime(endTime);
			result.put(pattern, pidRecord[0]);
			pattern = new RecordPattern("PrivateDirty内存-" + pid, "MB", "Memory");
			pattern.setStartTime(startTime);
			pattern.setEndTime(endTime);
			result.put(pattern, pidRecord[1]);

PSS内存,PrivateDirty内存数据存储在pidRecord,该数据来源于 appMemory 赋值
appMemory.put(processNames[i], saveRecord);

appMemory --> saveRecord —> record

// 记录数据
saveRecord[0].add(record[0]);
saveRecord[1].add(record[1]);
// 当前记录
RecordPattern.RecordItem[] record = new RecordPattern.RecordItem[]{
	new RecordPattern.RecordItem(System.currentTimeMillis(), pidMemoryInfo.getTotalPss() / 1024f, ""),
	new RecordPattern.RecordItem(System.currentTimeMillis(), pidMemoryInfo.getTotalPrivateDirty() / 1024f, "")};

record[0] 为pss内存,record[1]PrivateDirty内存

/**
         * Return total PSS memory usage in kB.
         */
        public int getTotalPss() {
            return dalvikPss + nativePss + otherPss + getTotalSwappedOutPss();
        }
		
		
/**
         * Return total private dirty memory usage in kB.
         */
        public int getTotalPrivateDirty() {
            return dalvikPrivateDirty + nativePrivateDirty + otherPrivateDirty;
        }

这两个为Debug.MemoryInfo方法

你可能感兴趣的:(安卓专项测试之内存及PerfDog和SoloPi比较)