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的时候,试着把它们缓存在数组中实现复用。
- 对于能够复用的对象,同理可以使用对象池将它们缓存起来。
其他、
分析面板
面板列名含义如下:
Name | 方法的详细信息,包括包名和参数信息 |
---|---|
col 3 is | right-aligned |
col 2 is | centered |
zebra stripes | are neat |
Incl Cpu Time | Cpu执行该方法该方法及其子方法所花费的时间 |
Incl Cpu Time % | Cpu执行该方法该方法及其子方法所花费占Cpu总执行时间的百分比 |
Excl Cpu Time | Cpu执行该方法所话费的时间 |
Excl Cpu Time % | Cpu执行该方法所话费的时间占Cpu总时间的百分比 |
Incl Real Time | 该方法及其子方法执行所话费的实际时间,从执行该方法到结束一共花了多少时间 |
Incl Real Time % | 上述时间占总的运行时间的百分比 |
Excl Real Time % | 该方法自身的实际允许时间 |
Excl Real Time | 上述时间占总的允许时间的百分比 |
Calls+Recur | 调用次数+递归次数,只在方法中显示,在子展开后的父类和子类方法这一栏被下面的数据代替 |
Calls/Total | 调用次数和总次数的占比 |
Cpu Time/Call | Cpu执行时间和调用次数的百分比,代表该函数消耗cpu的平均时间 |
Real Time/Call | 实际时间于调用次数的百分比,该表该函数平均执行时间 |
参考
https://www.youtube.com/watch?v=McAvq5SkeTk
Android 性能优化 - 彻底解决内存抖动相关推荐
- Android 性能优化 - 彻底解决内存泄漏
起源 有趣的灵魂千奇百怪,内存泄漏的也是各式各样 我在15年写过一遍 文章 < android中常见的内存泄漏和解决办法>http://blog.csdn.net/wanghao20090 ...
- Android性能优化系列之内存优化
在Java中,内存的分配是由程序完成的,而内存的释放是由垃圾收集器(Garbage Collection,GC)完成的,程序员不需要通过调用函数来释放内存,但也随之带来了内存泄漏的可能,上篇博客,我介 ...
- Android面试-Android性能优化和内存优化、APP启动速度一线大厂的实战案例解析
一.Android 内存管理机制 二.优化内存的意义 三.避免内存泄漏 四.优化内存空间 五.图片管理模块的设计与实现 六.总结 深入探索Android内存优化 第一章.重识内存优化 第二章.常见工具 ...
- Android 性能优化 之谈谈Java内存区域
最近一年副业主要在学习投资和技能学习,把以前学习内存分析的一些笔记总结发出来,写了很多笔记总结都没有写完就又忙着了,最近再次总结复习学习一遍,还有提醒各位同学一定要学会投资.. 了解Android 内 ...
- Android性能优化(三):响应优化
Android性能优化(三):响应优化 性能优化系列文章: Android性能优化(一):APP启动优化 Android性能优化(二):UI布局优化 Android性能优化(三):响应优化 Andro ...
- Android性能优化系列之apk瘦身
Android性能优化系列之布局优化 Android性能优化系列之内存优化 为什么APK要瘦身.APK越大,在下载安装过程中,他们耗费的流量会越多,安装等待时间也会越长:对于产品本身,意味着下载转化率 ...
- Android性能优化(一):APP启动优化
Android性能优化(一):APP启动优化 性能优化系列文章: Android性能优化(一):APP启动优化 Android性能优化(二):UI布局优化 Android性能优化(三):响应优化 An ...
- Android性能优化之利用强大的LeakCanary检测内存泄漏及解决办法
本篇文章主要介绍了Android性能优化之利用LeakCanary检测内存泄漏及解决办法,有兴趣的同学可以了解一下. 目录 前言 什么是内存泄漏? 内存泄漏造成什么影响? 什么是LeakCanary? ...
- Android性能优化:手把手教你如何让App更快、更稳、更省(含内存、布局优化等)...
2019独角兽企业重金招聘Python工程师标准>>> 前言 在 Android开发中,性能优化策略十分重要 因为其决定了应用程序的开发质量:可用性.流畅性.稳定性等,是提高用户留存 ...
最新文章
- 用Eclipse开发JavaWeb项目:错误信息 javax.servlet.http.HttpServlet was not found on the Java Build Path...
- Red Hat 更新yum源为centos,并安装c环境
- PIC最简约的PWM波形产生程序(PIC16F877A)
- 【物联网】 AR9344开发环境的搭建和编译固件
- 【php内核与扩展开发系列】PHP生命周期---启动、终止与模式
- JAVA HASHMAP 用法
- AcWing之重建二叉树
- 福昕风腾pdf导出为html,福昕风腾PDF套件快速指引.pdf
- 校园导游图的课程设计(三)
- keybd_event()使用方法
- CSS 小结笔记之伸缩布局 (flex)
- index.php文件分析,OpenCart index.php分析
- Futter基础第7篇: 实现底部导航
- 华为手机进工程模式指令大全
- 计量经济学——试题总结
- Guitar Pro8版本 吉他绘谱创作乐谱
- 如何禁止用户删除计算机服务,怎样才能禁止别人删除我电脑中的文件?
- oracle toad 价格,Toad for oracle 软件产品模块对比,方便大家选型。
- 开心网创始人兼CEO程炳皓
- 育英oj——LZY逃命路线总数
热门文章
- MES管理信息系统源码 MES源码
- 抖音直播间带货最新玩法和运营技巧
- 有小数点保留2位小数,没有小数点保留整数
- 基于springboot+vue的养老院管理系统
- pip安装ERROR: Could not install packages due to an OSError: [Errno 28] No space left on device解决方案
- marvel wifi 驱动分析
- 【面试】京东数据分析工程师(暑期实习)
- 云计算最高境界:手中无剑 心中有剑
- 文本样式,CSS字体和背景
- git mr 怎样合并部分_系统掌握Git之—分离头指针与合并操作