Android内存泄露分析简要思路

本文介绍了一种实用的方法来判断和定位Android应用中的内存泄露问题。首先介绍了如何利用adb命令检查应用内存使用情况,并通过DDMS工具确认内存泄露的存在。接着详细说明了如何使用hprof文件及MAT工具分析内存快照,定位潜在的泄露源。对于更复杂的场景,还提供了深入分析Native层内存泄露的方法。


工作中遇到挺多需要分析内存泄露问题的情况,现在大致简要写下思路,等之后时间相对比较充裕再进行补充。


1.明白内存泄露的判断依据?

个人总结为:持续增加,只增不减!

理解一下这8个字,配合几个命令和工具来确定一下你的应用是否存在内存泄露问题,这是很关键的,如果一开始就判断错误了,那么没有继续往下进行的理由。

命令如下: 

adb shell

dumpsys meminfo 应用包名 [当然,比较粗略地话,可以用adb shell procrank]

这时候你可以看到一个内存使用情况表



而我们首先关注的是TOTAL这个值,譬如你会执行某个脚本,或者Monkey在不断操作你的应用,你可以隔半个小时观察一次TOTAL的情况,如果持续增加,那么十有八九是有内存泄露的问题了,但是也并不是绝对,这时候你就要配合上DDMS工具来做分析了。(DDMS里面有一项Heap,里面可以Cause GC,如果你发现你执行了GC之后,依旧内存没有什么太大的减少,那么恭喜你,这部分内存泄露了。)


2.根据第一步所阐述的一个情况,大概可以判断出是否有内存泄露,那么接着需要做什么呢?

如果内存泄露,那么我们该做些什么呢?

思路:必定我们想要找到泄露点,那么如何找到?


(1). 你需要抓取hprof文件,这个文件可以呈现出一些内存的使用情况,不过切记,你别清除了进程再来抓这个文件,然后配合着MAT把这个hprof文件分析了

(MAT分析hprof文件的这方面知识网上太齐全了,读者们可以自己去学习一下哈,这里就不累赘)


(2).如果MAT分析出来的东东,你实在看不出什么猫腻,那么再次恭喜你,你中大招了。

这时候你要继续观察dumpsys meminfo 包名, 输出的结果信息,关注点放在 UnKnown那一行 和 Native Heap 那一行,关注Heap Alloc 或者 Pss Total, 

如果你的总TOTAL一直再增加,但是是由于这两行的增加,那么这个问题你不需要再继续在MAT上花时间了,因为这种内存泄露问题,出在Native层(C)

那么你需要去找你程序中使用到JNI的地方,so库或者其他一些特殊调用上,分析它们是否可能造成内存泄露问题。


(3)当然兴许你依旧没有头绪,那么没关系,另一个命令就是为了你而存在的,(首先某个应用的PID号, 用dumpsys meminfo 包名,那边已经可以查到)

譬如我上面那个mms, PID号为2786, 接着adb shell showmap -a PID号 (adb shell showmap -a 2786)

然后根据结果[....]这的信息,在去google上面找关键字, 譬如:[ anon ] bash的堆


(4)当你最终还是不知道是由哪边的.so库引起的话,你可以查看下Native Heap的内存分配情况,这时候你依旧需要借助DDMS,

需要先执行以下命令:

adb shell setprop libc.debug.malloc 1

adb shell stop

adb shell start


然后你还需要改一下eclipse中的配置参数值【因为如果你不配置的话,你的DDMS打开默认是看不到Native Heap那个Tab项的】

在ddms.cfg文件(实在找不到的话,就用Everything搜索下吧)最后增加一行native=true并save。ddms.cfg位于c:\Users\xxx\.android目录下。

在Device中选择好你要的应用的包名项,然后按下Snapshot按钮, 就可以观察到Native Heap的使用情况了,然后反复执行脚本,再观察观察,你会找到你需要的东西的。


(5)内存泄露的问题可能很复杂,但是有的时候有了这些技巧,相对更重要。所以第(5)小点,额外再提供一些其他的命令技巧,帮助查找另外的情况出现内存泄露的问题。

1.  adb shell dumpsys activity    查询activity栈的情况(曾遇到过,就是activity一直堆积,导致的内存溢出OOM)

        2.  adb shell dumpsys cpuinfo

        3.  adb shell dumpsys battery

 

如果你在这方面有自己其他的一些方法,那么也不妨留言跟大家分享下!


文件:/proc/meminfo

          /proc/buddyinfo

简单粗暴就直接通过: showmap 命令 多次,然后对比一下,看哪个增长得最明显。


转载请注明:http://blog.youkuaiyun.com/ljphhj/article/details/44966023

转载于 胖虎 优快云



<think>好的,用户的问题是关于如何在Android Studio中优化动画的流畅性。我需要先回忆一下之前学过的相关知识,尤其是关于Android性能优化的内容。记得之前看到过引用里的信息,里面提到了使用ViewPropertyAnimator和ObjectAnimator,还有避免过时的Animation类。这些都是关键点。 首先,用户提到动画性能问题,可能涉及到UI线程的阻塞、过度绘制或者动画本身的效率。我应该分步骤来解答,确保结构清晰。可能需要从工具分析开始,比如使用Overdraw工具检测过度绘制,然后提到使用合适的动画API,比如ViewPropertyAnimator,因为它更高效。另外,硬件加速和减少布局层级也是常见的优化方法。 还要考虑用户的实际操作,比如如何在代码中实现这些优化。例如,展示如何使用ViewPropertyAnimator来简化动画代码,同时提高性能。可能还需要提到属性动画和补间动画的区别,为什么属性动画更好。 另外,引用中提到的避免使用过时的Animation类,这点很重要,需要强调。同时,可能用户遇到的问题不仅仅是动画本身,还有可能是内存泄漏或者频繁的垃圾回收,这部分是否需要提及呢?可能需要简要提到内存管理,比如避免在动画中创建过多对象。 还要检查是否有其他优化点,比如使用硬件层(layerType),在动画期间临时提升渲染性能,但结束后要记得清除,以免增加内存开销。此外,提到Profiler工具来分析性能瓶颈,比如CPU、内存和GPU的使用情况,帮助定位问题。 用户可能对具体步骤不太清楚,所以需要给出具体的建议,比如使用哪些工具、如何修改代码示例。同时,确保语言通俗易懂,避免过于技术化的术语,但又要准确无误。 最后,生成相关问题时要围绕用户的问题扩展,比如分析工具的使用、不同动画框架的选择、性能优化案例等。确保问题有针对性,能够帮助用户进一步学习。 现在需要把这些思路整理成一个结构化的回答,分点说明,每个点包含方法和示例,最后添加相关问题。同时,注意引用来源的正确标注,比如引用[^1]中的优化动画部分。</think>在Android Studio中优化动画流畅性,可以按以下步骤进行: ### 一、使用现代动画API 1. **优先选择属性动画** 使用`ViewPropertyAnimator`实现简单属性动画,相比传统`Animation`类更高效: ```java view.animate() .translationX(100f) .setDuration(300) .start(); ``` 复杂动画建议采用`ObjectAnimator`,支持自定义属性和插值器: ```java ObjectAnimator.ofFloat(view, "alpha", 0f, 1f) .setDuration(500) .start(); ``` 2. **避免使用补间动画** 传统`AnimationUtils.loadAnimation()`实现的补间动画仅修改绘制位置,不改变实际视图属性,易导致视觉与逻辑位置不一致。 ### 二、性能分析工具 1. **Overdraw检测** 在开发者选项中开启"调试GPU过度绘制",蓝色/绿色为正常层级,红色区域需优化: - 减少`Background`重复绘制 - 使用`canvas.clipRect()`限制绘制区域 2. **Profile GPU Rendering** 通过条形图观察渲染耗时,超过16ms的帧需优化: ```bash adb shell dumpsys gfxinfo <package-name> ``` ### 三、渲染优化技巧 1. **启用硬件加速** 在AndroidManifest.xml中针对Activity配置: ```xml <activity android:hardwareAccelerated="true" /> ``` 复杂动画中临时启用硬件层: ```java view.setLayerType(View.LAYER_TYPE_HARDWARE, null); // 动画完成后恢复 animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { view.setLayerType(View.LAYER_TYPE_NONE, null); } }); ``` 2. **减少布局层级** 使用`Layout Inspector`分析视图结构,超过10层的嵌套布局应考虑: - 用`<merge>`标签合并重复布局 - 将复杂ItemView转换为`ViewStub`延迟加载 ### 四、内存与线程管理 1. **避免内存泄漏** 在Fragment/Activity销毁时取消动画: ```java @Override protected void onDestroy() { animator.cancel(); super.onDestroy(); } ``` 2. **异步处理复杂计算** 将贝塞尔曲线等复杂运算移至工作线程: ```kotlin CoroutineScope(Dispatchers.Default).launch { val pathPoints = calculateBezierPath() withContext(Dispatchers.Main) { updateViewPosition(pathPoints) } } ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值