内存泄漏、资源泄漏、空指针等问题的分析与总结
来源:互联网 发布:linq.js where. First 编辑:程序博客网 时间:2024/05/20 04:27
一、内存泄漏(ACTIVITY_LEAK)
1、静态变量持有Activity对象,导致Activity无法释放
1 2 3 4 5 6 7 8 9 10 11 12 13
public class MainActivity extends Activity{ private static Context mContext; private static View mView; @override protected void onCreated(Bundle savedInstatenceState){ super.onCreated(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; //..........1 mView = new View(this); //..........2}
}
解决方法:杜绝静态变量持有activity
2、单例模式持有Activity对象,导致Activity无法释放
在GameNotFreeFlowDialogActivity.onCreate方法中调用了单例类FreeFlowUtil的showMessageDialog()方法,
其中FreeFlowUtil的showMessageDialog()方法中第一个参数需要传入Context类。
由于FreeFlowUtil类为单例模式,生命周期与JVM相同(与application相同),在FreeFlowUtil类创建了mChinaUnicomAlertDialog对象并传入了GameNotFreeFlowDialogActivity的Context,导致Context生命周期(GameNotFreeFlowDialogActivity的生命周期)同FreeFlowUtil相同,导致了泄漏问题。
解决方法:
方法一:不用单例模式
方法二:将Activity的Context改为Application的Context:getApplicationContext(),这样单例模式持有的就不是单个activity了
注意:不是所有的Activity的Context都可以替换为getApplicationContext(),getApplicationContext()在startActivity时要新建task,而且在任何时候都不能创建dialog
3、属性无限循环动画持有了Activity里的View,View持有Activity对象,导致Activity无法释放
属性动画中的无限循环动画,在activity的onDestroy中没有停止,导致动画持有了activity的view,view又持有了activity
解决方法:在activity的onDestroy中停止动画
4、 handler导致的内存泄漏(非静态内部类持有外部类的引用导致的内存泄漏)
当handler内部类在不停的处理消息,或者handler内部类在消息发送很长一段时间才处理,会导致内存泄漏。
由于handler是非静态内部类他是一定会持有外部类的引用的,它又在不停的处理消息(或者当activity不可见是它仍在处理消息),所以它一直持有activity对象,导致Activity无法释放
在 Java 语言中,非静态内部类、匿名内部类将持有一个对外部类的隐式引用,而静态内部类则不会持有一个对外部类的隐式引用。
解决方法:
方法一:所以要将handler内部类改为静态内部类;如果需要传入外部类的对象,那么hanler初始化时传入外部类的对象要是弱引用;将所有引用的外部类成员使用WeakReference对象。
方法二:在activity的onDestroy的时候手动清除Message
@Override protected void onDestroy() { super.onDestroy(); mHandler.removeCallbacksAndMessages(null); // 需要在Activity生命周期结束时清除掉CallbacksAndMessages }
5、小结
禁止任何生命周期与activity生命周期不一致的结构持有activity,结构包括(静态变量、单例模式、动画、生命周期不一致的非静态内部类、匿名类)。有人说了那静态内部类不也和activity生命周期不一致吗,因为是静态不要紧啊只要不持有activity就没事啊,而静态内部类则不会持有一个对外部类的隐式引用。所以只要不持有就没事。
6、其他解决内存泄漏优化内存的方法
(1)java中的基本方法
*使用字符串与包装类时,尽量用直接量创建
*使用StringBuilder和StringBuffer进行字符串连接(而不用String,因为会造成多个对象)
*尽早释放无用的对象引用(及时赋为null)
*尽量少用静态变量
*避免在循环中创建java对象
*缓存经常使用的对象(使用hashmap缓存)
*考虑弱引用、软引用
(2)android中的方法
* 布局尽量减少层级
*布局尽量减少颜色重绘
*默认图片以加载的形式加载,不放在布局background中
*缩小图片大小,能用.9图的用.9图
二、资源泄漏(RESOURCE_LEAK)
及时对资源进行关闭,对于Try catch语句,需要在Finally分支下保证关闭。
public static String getFileMD5(File file) {if (!file.isFile()) {return null;}MessageDigest digest = null;FileInputStream in = null;byte buffer[] = new byte[1024];int len;try {digest = MessageDigest.getInstance("MD5");in = new FileInputStream(file);while ((len = in.read(buffer, 0, 1024)) != -1) {digest.update(buffer, 0, len);}} catch (Exception e) {e.printStackTrace();return null;}finally {CommonUtils.closeQuietly(in); //及时关闭}return bytesToHexString(digest.digest());}
/** * 静默关闭申请资源,防止产生 RESOURCE_LEAK * @param closeable */public static void closeQuietly(Closeable closeable) {if (closeable != null) {try {closeable.close();} catch (Exception ex) {// TODO: 2016/1/15 Log or ignore}}}三、空指针(NULL_DEREFERENCE)
一般未对引用判空鉴定。判空即可
- 内存泄漏、资源泄漏、空指针等问题的分析与总结
- Android内存泄漏分析与总结
- 内存泄漏问题总结
- 内存泄漏问题总结
- InputMethodManager引起的内存泄漏问题分析与解决
- Java内存泄漏简单的分析总结
- 安卓的内存泄漏问题总结
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- 【java内存泄漏的定位与分析】
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- java内存泄漏的定位与分析
- xml pull 解析 XlistView 上拉加载 下拉刷新
- Android EditText得到和失去焦点时,自定义处理内容
- typename用法
- 百度地图检索的实现
- POJ1127——Jack Straws(计算几何,直线相交)
- 内存泄漏、资源泄漏、空指针等问题的分析与总结
- 调试案例明白断点调试的重要性
- Android 获取android手机信息
- 练习5-18 修改dcl程序,使它能够处理输入中的错误
- 自定义JNI常用函数宏
- HttpUtils请求
- ImageLoader
- grails3项目UrlMapping实现伪静态配置
- ndarray 数据类型 —— dtype