引言今天又是没什么事情,好,不多说,直接进入我们的主题吧。
今天说的是关于内存泄漏的检测与解决。这个问题想必对于初学者是个迷,也不知道从何出入手,那么今天这个文章可以帮助你,,如果有什么地方写的不好,请谅解,毕竟我还是个孩子!!!找出内存泄漏与解决请各位同学打开我们的开发工具(AS),来跟我一起写个内存泄漏的项目(嘻嘻)。不多说,上代码!!!/**
* Author lingchen
* Email [email protected]
* Time 2016/11/3
* Function 测试内存泄漏
*/
public class MainActivity extends AppCompatActivity {
private static final String TAG = "Activity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/**
* 跳转到测试内存泄漏的activity
*/
public void onGoTestLeaked(View view) {
startActivity(new Intent(this, TestLeakedActivity.class));
}
@Override
protected void onDestroy() {
Log.e(TAG, "MainActivity -- > onDestroy() called");
super.onDestroy();
}<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="match_parent"
android:onClick="onGoTestLeaked"
android:text="点我,我就泄漏给你看" />
</RelativeLayout>别告诉我你看不懂,下面就是我们今天关注的类了,上代码 /**
* Author lingchen
* Email [email protected]
* Time 2016/11/3
* Function 测试类
*/
public class TestLeakedActivity extends AppCompatActivity {
private static final String TAG = "Activity";
public static TestLeaked testLeaked;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testleaked);
testLeaked = new TestLeaked();
}
/**
* 内存泄漏类
*/
public class TestLeaked {
}
@Override
protected void onDestroy() {
Log.e(TAG, "TestLeakedActivity -- > onDestroy() called");
super.onDestroy();
}
}好了,相比大家一看到public static TestLeaked testLeaked;就会知道,这个变量的生命周期就是隶属于appliction了(别问我为啥哈)。那好testLeaked = new TestLeaked();这段代码直接new 一个内部类(会引用Activity)指向静态变量。这样如果我多次进入这个界面,会出现什么效果呢?来跟我一起做,拿起鼠标,打开最下方的Android Monitor,然后选中
但是呢?不对啊,按理说,我们是多次new TestLeaked()复制给静态变量的,那么以前被他引用的对象就应该释放了啊,内存中应该不会存在这么多的TestLeakedActivity实力啊,按理说只有一个TestLeakedActivity才对呀,难道是回收不及时导致的么?,那好我们手动调用下GC ![]() 然后在截取下内存信息 ![]() 哈哈,果然就是没有即使被回收,那么我们说的是对的。上面图片说明了一切。好了既然都找到了内存泄漏的原因,那就去把代码改下喽, ![]() 这是第一种办法,第二种办法如下 ![]() 好了,更改之后,我们使用第二种方法运行下(理想应该是,TestLeakedActivity不应该存在,内部类TestLeaked存在),好了 运行下,顺便点下GC。 ![]() 在点开内部类 ![]() 好了 完美。 防止内存泄漏,养成良好编码习惯这个话题网上有太多的文章了,我这边就是写下我自己认为要特别注意的地方:
1.谨慎使用static变量,即使使用了,要即使施放强引用的地址,尤其是List,即使清理。
2.单例类的context应该使用Appliction。
3.好好管理handler,在退出的时候,应该调用handler.removeCallbacksAndMessages(null)。
4.管理好线程,例如网络请求,应该在退出的时候,取消网络请求。动画也是,及时的停止动画回收资源。
5.结合WeakReference(弱引用),SoftReferecne(软引用)使用。
6.尽量限制service生命周期,如果完成任务后就关闭service,那么使用IntentService。
....想不到了。总结就一句话:注重生命周期 |
|
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系
[邮箱地址] 删除
|