Android Memory Leak
线程也是造成内存泄露的一个重要的源头。线程产生内存泄露的主要原因在于线程生命周期的不可控。
1.看一下下面是否存在问题
public class ThreadActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyThread().start();
}
private class MyThread extends Thread {
@Override
public void run() {
super.run();
dosomthing();
}
}
private void dosomthing(){
}
}
这段代码很平常也很简单,是我们经常使用的形式。
真的没有问题吗?
我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,
一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。
2.这种线程导致的内存泄露问题应该如何解决呢?
• 第一、将线程的内部类,改为静态内部类。
• 第二、在线程内部采用弱引用保存Context引用。 代码如下:
public class ThreadAvoidActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new MyThread(this).start();
}
private void dosomthing() {
}
private static class MyThread extends Thread {
WeakReference mThreadActivityRef;
public MyThread(ThreadAvoidActivity activity) {
mThreadActivityRef = new WeakReference(
activity);
}
@Override
public void run() {
super.run();
if (mThreadActivityRef == null)
return;
if (mThreadActivityRef.get() != null)
mThreadActivityRef.get().dosomthing();
// dosomthing
}
}
}
上面的两个步骤其实是切换两个对象的双向强引用链接
1. 静态内部类:切断Activity 对于 MyThread的强引用。
2. 弱引用: 切断MyThread对于Activity 的强引用。
3.AsynTask 内部类会如何呢?
我们思考一个问题:假设MyThread的run函数是一个很费时的操作,当我们开启该线程后,将设备的横屏变为了竖屏,
一般情况下当屏幕转换时会重新创建Activity,按照我们的想法,老的Activity应该会被销毁才对,然而事实上并非如此。
由于我们的线程是Activity的内部类,所以MyThread中保存了Activity的一个引用,当MyThread的run函数没有结束时,
MyThread是不会被销毁的,因此它所引用的老的Activity也不会被销毁,因此就出现了内存泄露的问题。代码如下:
public abstract class WeakAsyncTask<Params, Progress, Result, WeakTarget>
extends AsyncTask<Params, Progress, Result> {
protected WeakReference mTarget; public WeakAsyncTask(WeakTarget target) {
mTarget = new WeakReference(target);
} @Override
protected final void onPreExecute() {
final WeakTarget target = mTarget.get();
if (target != null) {
this.onPreExecute(target);
}
} @Override
protected final Result doInBackground(Params... params) {
final WeakTarget target = mTarget.get();
if (target != null) {
return this.doInBackground(target, params);
} else {
return null;
}
} @Override
protected final void onPostExecute(Result result) {
final WeakTarget target = mTarget.get();
if (target != null) {
this.onPostExecute(target, result);
}
} protected void onPreExecute(WeakTarget target) {
// Nodefaultaction
} protected abstract Result doInBackground(WeakTarget target,
Params... params); protected void onPostExecute(WeakTarget target, Result result) {
// Nodefaultaction
}
}
Android Memory Leak的更多相关文章
- Android 内存优化 (防Memory Leak)
在之前的 Android 内存管理 &Memory Leak & OOM 分析 中,说到了Android的内存管理相关的原理,也能了解到Android Memory Leak 和 ...
- Android 内存管理 &Memory Leak & OOM 分析
转载博客:http://blog.csdn.net/vshuang/article/details/39647167 1.Android 进程管理&内存 Android主要应用在嵌入式设备当中 ...
- Android Memory/Resource Leak总结
Android的内存/资源泄露,不容易发现,又会引发app甚至是system的一系列问题. 在这里我根据以往碰到的相关问题,总结出了一些检测和修改方法. *有可能造成memory leak的代码是Fr ...
- 安卓android WebView Memory Leak WebView内存泄漏
Android WebView Memory Leak WebView内存泄漏 在这次开发过程中,需要用到webview展示一些界面,但是加载的页面如果有很多图片就会发现内存占用暴涨,并且在退出该界面 ...
- Android 内存管理 &Memory Leak & OOM 分析
1.Android 流程管理&内存 Android主要应用在嵌入式设备其中.而嵌入式设备因为一些众所周知的条件限制,通常都不会有非常高的配置,特别是内存是比較有限的. 假设我们编写的代 码其中 ...
- Android 常见 Memory Leak 原因及解决办法总结
待整理: http://geek.csdn.net/news/detail/50692 背景 在Android开发过程中,我们经常碰到的情况就是在我们不清楚为什么情况下,程序突然出现Crash了.其中 ...
- 内存泄漏(Memory Leak)
什么情况下会导致内存泄露(Memory Leak)? Android 的虚拟机是基于寄存器的Dalvik,它的最大堆大小一般是16M,有的机器为24M.因此我们所能利用 的内存空间是有限的.如果我们的 ...
- quartz集群报错but has failed to stop it. This is very likely to create a memory leak.
quartz集群报错but has failed to stop it. This is very likely to create a memory leak. 在一台配置1核2G内存的阿里云服务器 ...
- 山东省第七届ACM省赛------Memory Leak
Memory Leak Time Limit: 2000MS Memory limit: 131072K 题目描述 Memory Leak is a well-known kind of bug in ...
随机推荐
- 独立硬盘冗余阵列与HDFS
http://zh.wikipedia.org/wiki/RAID 独立硬盘冗余阵列(RAID, Redundant Array of Independent Disks),旧称廉价磁盘冗余阵列(Re ...
- C++:类成员函数的重载、覆盖和隐藏区别?
#include <iostream> class A { public: void func() { std::cout << "Hello" <& ...
- iOS开发系列之运动事件
前面我们主要介绍了触摸事件以及由触摸事件引出的手势识别,下面我们简单介绍一下运动事件.在iOS中和运动相关的有三个事件:开始运动.结束运动.取消运动. 监听运动事件对于UI控件有个前提就是监听对象必须 ...
- wp-content-index文章目录插件使用效果调整
安装好wp-content-index后进行如下设置: 其中标红处必须标红,用于检索锚点.在文章页面添加如下js代码: $(function() { var wpindex = $("#co ...
- 《Android开发艺术探索》读书笔记 (10) 第10章 Android的消息机制
第10章 Android的消息机制 10.1 Android消息机制概述 (1)Android的消息机制主要是指Handler的运行机制,其底层需要MessageQueue和Looper的支撑.Mes ...
- python-Pickle序列化
[Python之旅]第三篇(二):Pickle序列化 python 序列化 pickle 摘要: 说明:关于Pickle的说明 作如下说明: 1 2 3 4 5 6 7 序列化的概念很简单 ...
- c - 计算1到20的阶乘
#include <stdio.h> /* 题目:求 1+2!+3!+...+20!的和 */ unsigned long long int factorial(long n) { uns ...
- java_annotation_01
一,Annotation简介 J2SE5.0提供了很多新的我,其中一个很重要的我就是对元数据的支持,在J2SE5.0中,这种元数据被称为注释,通过使用注释,程序开发人员可以在不改变原有逻辑的情况下,在 ...
- 分片传输——send和recv函数
最近在写socket编程收发数据,对于如何发送和接收大量数据,一直在思考.send和recv一般缓存区大小为4K,但是如果你要传输的数据超过了这个标准该如何做呢. 我想到的就是如改写write和rea ...
- GitHub-修改以下host-ip可加快访问速度
#GitHub START 207.97.227.239 github.com 204.232.175.94 gist.github.com 107.21.116.220 help. ...