内存泄露造成原因

  • 1.上下文对象
  • 2.碎片
  • 3.WindowManager等系统管理类
  • 4.Map
  • 5.List和Map類似
  • 6.接口回调
  • 7.View
  • 8.handler
  • 9.线程
  • 10.第三方库
  • 11.高德地图
  • 12.Dialog
  • 13.CountDownTimer

1.上下文对象

public class NaviLocationModel ... {private Context context;
public class NaviLocationModel ... {private static Context context;

如上两种情况都会造成内存泄露,无论 NaviLocationModel 是不是单例。如果非要全局 Context ,需要使用弱引用或者 aplication ;如果没有必要,在方法内部使用。这是最常见的内存泄露原因。

2.碎片

碎片不能使用static修饰,否则会内存泄露

3.WindowManager等系统管理类

WindowManager等系统管理类不能被static修饰,否则会内存泄露,而且也没有必要,因为WindowManager等本来就是唯一。

4.Map

Map 导致的内存泄露:https://blog.csdn.net/weixin_35691921/article/details/117035421

5.List和Map類似

6.接口回调

public class LeakTextManager {private static LeakTextManager instance;private LeakTextManager() {}public static LeakTextManager getInstance() {if (instance == null) {instance = new LeakTextManager();}return instance;}private OnUiCallback<String> onUiCallback;public void setOnUiCallback(OnUiCallback<String> onUiCallback) {this.onUiCallback = onUiCallback;}
//Activity@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.leak_activity);findViewById(R.id.tv_test_7).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {LeakTextManager.getInstance().setOnUiCallback(new OnUiCallback<String>() {@Overridepublic void onSuccess(String s) {}@Overridepublic void onError(String code, String msg) {}});}});}

如上,点击测试按钮:
创建一个接口,传入到单例之中,并且在Activity关闭的时候没有移除,这样,就可以内存泄露了~

那么,如果在onDestory的时候移除从单例中移除当前接口,是不是就可以解决内存泄露了呢?试一下~

    @Overrideprotected void onDestroy() {super.onDestroy();LeakTextManager.getInstance().setOnUiCallback(null);onUiCallback =null;}

这样就可以了,确实没有泄露。(。•́__ก̀。)

如果是:

    @Overrideprotected void onDestroy() {super.onDestroy();//LeakTextManager.getInstance().setOnUiCallback(null);onUiCallback =null;}

这样会泄露吗?

会的哦,因为这样只是让 onUiCallback 不指向我们之前创建的对象的内存地址,但是单例类中的onUiCallback对象还有指向创建对象的内存地址,所以会有内存泄露。

除此之外,像这种Activity 与单例类之间的数据交互,中间应该再加上一弱引用层,用来阻断Activity和单例类存在的强引用关系。

7.View

将View 传入其他类中缓存起来用,比如你想在封装类内部修改View的变换,这可能会产生内存泄露,
比如封装类是静态,因为View会持有Context,所以相当于在静态中缓存了Context,使得Coxtext不能释放从而泄露。

8.handler

略…

9.线程

略…

public class WelcomeActivity extends Activity {......public void sel(){new Thread(new Runnable() {@Overridepublic void run() {SystemClock.sleep(10000);//do something ... 里面持有对当前activity的引用}}).start();}
}

10.第三方库

第三方库最好还是下载下来再用,因为有些人封装代码的时候没有考虑内存泄露,需要修改。

11.高德地图

问题1:MapView

描述:Activity 关闭的时候,位于Fragment的layout内的MapView出现泄露

修改:

            mapView = new MapView(getContext());relativeLayout.addView(mapView);

注:我以为这种写法也会有泄露,但是并没有被检测出来,目前看的话是可以解决内存泄露的
时间:20210525

或者

            mapView = new MapView(getContext().getApplicationContext());relativeLayout.addView(mapView);

12.Dialog

举例演示泄露,如下问题代码:

封装Dialog:

public class LoadingDialog extends Dialog {... ...public LoadingDialog(Context context, String toastText, int timer) {super(context, R.style.loading_dialog);setContentView(R.layout.dialog_loading);... ...Observable.timer(30, TimeUnit.SECONDS).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new SimpleObserver<Long>() {@Overridepublic void onSubscribe(Disposable d) {super.onSubscribe(d);mDisposable = d;}@Overridepublic void onAction(Long aLong) {}@Overridepublic void onComplete() {super.onComplete();if (isShowing()) {dismiss();}}});}@Overridepublic void dismiss() {super.dismiss();RxJavaGcManager.getInstance().disposableActive(mDisposable);... ...}.... ....}

对Dialog的使用进行封装:

public class Loading {private static final Loading instance = new Loading();private Dialog dialog;private static final int DEFAULT = 0;public static Loading getInstance() {return instance;}public void show(Context context) {dismiss();dialog = new LoadingDialog(context, context.getResources().getString(R.string.dialog_loading), DEFAULT);dialog.setCanceledOnTouchOutside(true);dialog.show();}public void dismiss() {if (dialog != null) {dialog.cancel();if (dialog.isShowing()) {dialog.dismiss();}dialog = null;}}}

使用:

public class MainActivity extends ... Activity ...{... ....@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);req();}public void req() {Loading.getInstance().show(getContext());ReqFenceSettingParams reqFenceSettingParams = new ReqFenceSettingParams();reqFenceSettingParams.set(...);reqFenceSettingParams.set(...);DataModel.instance().reqHttpData(reqFenceSettingParams, ..., new OnUiCallback<ResponseNull>() {@Overridepublic void onSuccess(ResponseNull responseNull) {... ...Loading.getInstance().dismiss();}@Overridepublic void onError(String code, String msg) {... ...Loading.getInstance().dismiss();}});}

以上,就是问题代码的调用了。

直接说结论了:

如何引起内存泄露?
当Dialog超时自动消去或者手击蒙版消去后,退出Activity,这样的操作就会引起内存泄漏。

什么原因?
原因是 LoadingDialog 虽然dismiss了,但是 Loading 类中的 private Dialog dialog;对象并没有失去引用,因为 Loading 类是静态类,所以可以认为 private Dialog dialog;也是静态的, private Dialog dialog;对象含有Activity的引用,所以当Activity退出的时候会泄露。

解决?
直接在退出Activity的时候,设置 private Dialog dialog; 是null即可。

13.CountDownTimer

CountDownTimer 里面又有线程,又有handler,需要调用回收的方法。

    /*** Cancel the countdown.*/public synchronized final void cancel() {mCancelled = true;mHandler.removeMessages(MSG);}

常见造成内存泄露的原因相关推荐

  1. .NET中常见的内存泄露问题——GC、委托事件和弱引用

    其实吧,内存泄露一直是个令人头疼的问题,在带有GC的语言中这个情况得到了很大的好转,但是仍然可能会有问题. 一.什么是内存泄露(memory leak)? 内存泄露不是指内存坏了,也不是指内存没插稳漏 ...

  2. Android中常见的内存泄露

    内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏.内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会 ...

  3. UWP开发入门(十六)——常见的内存泄漏的原因

    原文:UWP开发入门(十六)--常见的内存泄漏的原因 本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)--用Diagno ...

  4. Eclipse Memory Analyzer以及内存泄露的原因

    Eclipse Memory Analyzer是一个非常棒的堆内存分析工具,是JDK自带的堆分析工具jhat的一个非常好的替代品,能够快速地定位Java内存泄露的原因.       可能有的同学会问, ...

  5. Android开发中常见的内存泄露案例以及解决方法总结

    Android开发中常见的内存泄露案例以及解决方法总结 参考文章: (1)Android开发中常见的内存泄露案例以及解决方法总结 (2)https://www.cnblogs.com/shen-hua ...

  6. 面试:Handler内存泄露的原因是什么?

    前言 嗨,大家好,问大家一个"简单"的问题: Handler内存泄露的原因是什么? 你会怎么答呢? 这是错误的回答 有的朋友看到这个题表示,就这?太简单了吧. "内部类持 ...

  7. Java内存泄露系列--内存泄露的原因及解决方案(大全)

    原文网址:Java内存泄露系列--内存泄露的原因及解决方案(大全)_IT利刃出鞘的博客-CSDN博客 简介 简介 本文介绍Java中内存泄露的一些原因与解决方案. 如果内存泄露的空间足够大,就会导致内 ...

  8. 内存泄露的原因找到了,罪魁祸首居然是 Java TheadLocal

    作者 | 雷架 来源 | 爱笑的架构师(ID:DancingOnYourCode) ThreadLocal使用不规范,师傅两行泪 组内来了一个实习生,看这小伙子春光满面.精神抖擞.头发微少,我心头一喜 ...

  9. Android下常见的内存泄露

    转自:http://www.linuxidc.com/Linux/2011-10/44785.htm 因为Android使用Java作为开发语言,很多人在使用会不注意内存的问题. 于是有时遇到程序运行 ...

最新文章

  1. Spring Boot 面试杀手锏:自动配置原理
  2. Java 11正式发布,新特性解读
  3. cascader 动态加载 回显_Element中的Cascader(级联列表)动态加载省\市\区数据的方法...
  4. spring14:注解@Autowired,实现引用类型的赋值
  5. redis-查看日志
  6. C#反射技术在多语言实现中的实际用处参考,让初学者学技术有个针对性【附源码】...
  7. 2个 string 日期比较
  8. pythonweb好难-(2017)我不建议使用的Python Web框架
  9. UE3 GPU性能和分析
  10. html清除div浮动,HTML_清除浮动的最优方法:CSS,在CSS森林群里讨论一个margin的 - phpStudy...
  11. node html响应头,nodejs 中http请求头,响应头
  12. 有N个软件包未被升级
  13. Postman下载与安装操作步骤(只有两步骤下载)
  14. 网站统计系统内容分析
  15. oracle 70个常用函数
  16. 程序员效率:整理常用的在线笔记软件
  17. 软件学院“SIdea”软件创意大赛
  18. 【解决】Expanding invalid MinMaxAABB
  19. NFT Insider #60:电讯盈科联同香港电讯进驻 The Sandbox,BreederDAO 团队登上《福布斯》封面
  20. ddmmyy日期格式是多少_英语中关于年月日以及数字

热门文章

  1. 北京党建展馆vr全景制作优点有哪些
  2. Android 微信套餐之绑定微信
  3. 一失脚为千古恨,再回头一百年人
  4. 【SSL】SSL 证书级别
  5. 惊!读取大脑重建高清视频,Stable Diffusion还能这么用
  6. 客户价值分析(聚类)--【Excel+SPSS】和python实现
  7. android开发返回主线程,安卓回到主线程的几种方式
  8. 【Python】使用生成器(yield from)和装饰器封装函数
  9. new,浅拷贝,深拷贝的区别
  10. argmax()、max()介绍