失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android 性能优化 - 彻底解决内存抖动

Android 性能优化 - 彻底解决内存抖动

时间:2018-08-17 16:55:22

相关推荐

Android 性能优化 - 彻底解决内存抖动

起源

内存抖动是由于短时间内有大量对象进出新生区导致的,它伴随着频繁的GC。

gc会大量占用ui线程和cpu资源,会导致app整体卡顿

android profile 效果图如下图

Memory 中

我们可以看到 上面的一溜白色垃圾桶。说明在大量的执行gc操作。用了一会儿 手机就开始卡了

学习内容

使用工具来快速定位 引起内存抖动的代码。学习 到什么样的 错误操作会导致内存都懂,如何避免。

快速定位内存抖动

快速定位 还得使用ddms。莫慌 as里面自带了

Tools->Android->Android Device Monitor

然后进行如下操作

然后我们看如下图片。

不要慌。

中间红框的就是我们要分析的内容,看他参差不齐的就是 内存抖动造成的。

然后我们把红框 内容放大。鼠标点住 然后往右拖动,就会变大,点击 红框上面的数字就会变小。

我们将 抖动的地方 放大后。随便点击会出现下图样式

可以看到这个粉色的拱门的 图案。从它的左边到右边 代表 一个函数 消耗的时间。

我们接下来 就快速定位有问题的代码在哪里

我就随便的滑动了一下,然后 随便的选中了一个, 然后下边就展示了 我所选中的 函数方法。

这里有一个细节

onClick 最前面 的序号是 9 Parent 下的方法 序号为8 children 下的方法序号为10

说明 onClick 的序号 大于onClick 调用的方法 的序号。小于 onClick 被调用的方法的序号。

如果我们一直点击Parent 下的方法就会找到 序号为1 的方法

如下图所示。

我们找到了错误代码在哪。那么我们就看一下 源代码的样子

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {imPrettySureSortingIsFree();}});}/*** 排序后打印二维数组,一行行打印*/public void imPrettySureSortingIsFree() {int dimension = 300;int[][] lotsOfInts = new int[dimension][dimension];Random randomGenerator = new Random();for (int i = 0; i < lotsOfInts.length; i++) {for (int j = 0; j < lotsOfInts[i].length; j++) {lotsOfInts[i][j] = randomGenerator.nextInt();}}for (int i = 0; i < lotsOfInts.length; i++) {String rowAsStr = "";//排序int[] sorted = getSorted(lotsOfInts[i]);//拼接打印for (int j = 0; j < lotsOfInts[i].length; j++) {rowAsStr += sorted[j];if (j < (lotsOfInts[i].length - 1)) {rowAsStr += ", ";}}}}public int[] getSorted(int[] input) {int[] clone = input.clone();Arrays.sort(clone);return clone;}}

发现 rowAsStr 对象在被不断地创建。 我们可以把它优化一下

public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {imPrettySureSortingIsFree();}});}/*** 排序后打印二维数组,一行行打印*/public void imPrettySureSortingIsFree() {int dimension = 300;int[][] lotsOfInts = new int[dimension][dimension];Random randomGenerator = new Random();for (int i = 0; i < lotsOfInts.length; i++) {for (int j = 0; j < lotsOfInts[i].length; j++) {lotsOfInts[i][j] = randomGenerator.nextInt();}}//优化以后StringBuilder sb = new StringBuilder();String rowAsStr = "";for(int i = 0; i < lotsOfInts.length; i++) {//清除上一行sb.delete(0,rowAsStr.length());//排序int[] sorted = getSorted(lotsOfInts[i]);//拼接打印for (int j = 0; j < lotsOfInts[i].length; j++) {//rowAsStr += sorted[j];sb.append(sorted[j]);if(j < (lotsOfInts[i].length - 1)){//rowAsStr += ", ";sb.append(", ");}}rowAsStr = sb.toString();Log.i("ricky", "Row " + i + ": " + rowAsStr);}}public int[] getSorted(int[] input) {int[] clone = input.clone();Arrays.sort(clone);return clone;}}

这样就不会内存抖动了

能找到问题,这个问题就基本解决了。

下面是避免发生内存抖动的几点建议:

尽量避免在循环体内创建对象,应该把对象创建移到循环体外。 注意自定义View的onDraw()方法会被频繁调用,所以在这里面不应该频繁的创建对象。 当需要大量使用Bitmap的时候,试着把它们缓存在数组中实现复用。 对于能够复用的对象,同理可以使用对象池将它们缓存起来。

其他、

分析面板

面板列名含义如下:

参考

/watch?v=McAvq5SkeTk

如果觉得《Android 性能优化 - 彻底解决内存抖动》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。