您的位置:首页 > 移动开发 > Android开发

android - 内存分析与内存优化

2016-01-07 14:20 281 查看
检测内存泄露问题的工具:DDMS(Dalvik调试监视服务器);MAT
(内存分析工具),MAT的eclipse插件

》Java的内存泄露的特点

Java中的内存泄露主要特征:可达,无用
无用指的是创建了但是不再使用之后没有释放
能重用但是却创建了新的对象进行处理

> Android内存

1.注意我们在Activity的onDestory方法中使用了handler.removeCallbacksAndMessages(null),这样子能保证LeakActivity退出的时候,每条Message的target
MyHandler也会被释放, 所以我们在使用非static的内部类的时候,要注意该内部类的生命周期是否比外部类要长,如果是的话我们可以使用上面的解决方法。

Handler handler;

@Override

protected void onDestroy() {

handler.removeCallbacksAndMessages(null);

super.onDestroy();

}

2.资源对象没有关闭,比如数据库操作中得Cursor,IO操作的对象

3.调用了registerReceiver注册广播后未调用unregisterReceiver()来取消

4.调用了View.getViewTreeObserver().addOnXXXListener ,而没有调用View.getViewTreeObserver().removeXXXListener

5.Android 3.0以前,没有对不在使用的Bitmap调用recycle(),当然在Android 3.0以后就不需要了,更详细的请查 看/article/1645771.html

6.Context的泄露,比如我们在单例类中使用Context对象,
假如我们在某个Activity中使用Singleton.getInstance(this)或者该实例,那么会造成该Activity一直被Singleton对象引用着,所以这时候我们应该使用getApplicationContext()来代替Activity的Context,getApplicationContext()获取的Context是一个全局的对象,所以这样就避免了内存泄露。相同的还有将Context成员设置为static也会导致内存泄露问题。

7.不要重写finalize()方法,我们有时候可能会在某个对象被回收前去释放一些资源,可能会在finalize()方法中去做,但是实现了finalize的对象,创建和回收的过程都更耗时。创建时,会新建一个额外的Finalizer
对象指向新创建的对象。 而回收时,至少需要经过两次GC,第一次GC检测到对象只有被Finalizer引用,将这个对象放入 Finalizer.ReferenceQueue 此时,因为Finalizer的引用,对象还无法被GC,

Finalizer$FinalizerThread 会不停的清理Queue的对象,remove掉当前元素,并执行对象的finalize方法,清理后对象没有任何引用,在下一次GC被回收,所以说该对象存活时间更久,导致内存泄露。

Unreachable对象指的是可以被垃圾回收器回收的对象,但是由于没有GC发生,所以没有释放,这时抓的内存使用中的Unreachable就是这些对象。



定义:
堆大小
分配给Java堆的内存,在Android平台,这些内存都是针对每个Activity分配的(这还取决于设备)
堆转储文件
一个包含了堆中信息的二进制文件
支配树(Dominator Tree)
一个用来图形化展示对象之间关系的工具,详情请参考wiki
内存泄露
内存泄露是指有个引用指向一个不再被使用的对象,导致该对象不会被垃圾回收器回收。如果这个对象有个引用指向一个包括很多其他对象的集合,就会导致这些对象都不会被垃圾回收。因此,需要牢记,垃圾回收无法杜绝内存泄露。
GC根
GC根是指那些假设可达的对象。 通常包括所有当前栈和系统的类加载器加载的类中引用的对象。(【译者注】栈里引用的对象是指当前执行的方法里的局部变量指向的对象,系统加载器加载的类引用的对象包括类的静态属性引用的对象)
1. WebView 控件:

使用了 WebView 控件一定要注意清理缓存 destroy() 方法,但之前必须调用 removeAllViews() 要不然有时出错

?
2.线程

在退出活动窗口时一定要注意开启的线程是否已经关闭,可以在debug查看线程的开启情况。

如果只是刷新Ui线程 建议不用线程可以使用 Handler 来刷新 方法如下。这种方法只能做简单的操作,复杂操作建议使用线程。

?
3 sqlite

使用sqlite是一定要注意 关闭当前指针 和数据库连接
》每当处理或者排查性能问题的时候,我都遵循这些原则:

持续测量: 用你的眼睛做优化从来就不是一个好主意。同一个动画看了几遍之后,你会开始想像它运行地越来越快。数字从来都不说谎。使用我们即将讨论的工具,在你做改动的前后多次测量应用程序的性能。

使用慢速设备:如果你真的想让所有的薄弱环节都暴露出来,慢速设备会给你更多帮助。有的性能问题也许不会出现在更新更强大的设备上,但不是所有的用户都会使用最新和最好的设备。

权衡利弊 :性能优化完全是权衡的问题。你优化了一个东西 —— 往往是以损害另一个东西为代价的。很多情况下,损害的另一个东西可能是查找和修复问题的时间,也可能是位图的质量,或者是应该在一个特定数据结构中存储的大量数据。你要随时做好取舍的准备。
Android应用程序中最典型的需要注意释放资源的情况是在Activity的生命周期中,在onPause()、onStop()、onDestroy()方法中需要适当的释放资源的情况。由于此情况很基础,在此不详细说明,具体可以查看官方文档对Activity生命周期的介绍,以明确何时应该释放哪些资源
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: