常见造成内存泄露的原因
内存泄露造成原因
- 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);}
常见造成内存泄露的原因相关推荐
- .NET中常见的内存泄露问题——GC、委托事件和弱引用
其实吧,内存泄露一直是个令人头疼的问题,在带有GC的语言中这个情况得到了很大的好转,但是仍然可能会有问题. 一.什么是内存泄露(memory leak)? 内存泄露不是指内存坏了,也不是指内存没插稳漏 ...
- Android中常见的内存泄露
内存泄漏是指无用对象(不再使用的对象)持续占有内存或无用对象的内存得不到及时释放,从而造成内存空间的浪费称为内存泄漏.内存泄露有时不严重且不易察觉,这样开发者就不知道存在内存泄露,但有时也会很严重,会 ...
- UWP开发入门(十六)——常见的内存泄漏的原因
原文:UWP开发入门(十六)--常见的内存泄漏的原因 本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)--用Diagno ...
- Eclipse Memory Analyzer以及内存泄露的原因
Eclipse Memory Analyzer是一个非常棒的堆内存分析工具,是JDK自带的堆分析工具jhat的一个非常好的替代品,能够快速地定位Java内存泄露的原因. 可能有的同学会问, ...
- Android开发中常见的内存泄露案例以及解决方法总结
Android开发中常见的内存泄露案例以及解决方法总结 参考文章: (1)Android开发中常见的内存泄露案例以及解决方法总结 (2)https://www.cnblogs.com/shen-hua ...
- 面试:Handler内存泄露的原因是什么?
前言 嗨,大家好,问大家一个"简单"的问题: Handler内存泄露的原因是什么? 你会怎么答呢? 这是错误的回答 有的朋友看到这个题表示,就这?太简单了吧. "内部类持 ...
- Java内存泄露系列--内存泄露的原因及解决方案(大全)
原文网址:Java内存泄露系列--内存泄露的原因及解决方案(大全)_IT利刃出鞘的博客-CSDN博客 简介 简介 本文介绍Java中内存泄露的一些原因与解决方案. 如果内存泄露的空间足够大,就会导致内 ...
- 内存泄露的原因找到了,罪魁祸首居然是 Java TheadLocal
作者 | 雷架 来源 | 爱笑的架构师(ID:DancingOnYourCode) ThreadLocal使用不规范,师傅两行泪 组内来了一个实习生,看这小伙子春光满面.精神抖擞.头发微少,我心头一喜 ...
- Android下常见的内存泄露
转自:http://www.linuxidc.com/Linux/2011-10/44785.htm 因为Android使用Java作为开发语言,很多人在使用会不注意内存的问题. 于是有时遇到程序运行 ...
最新文章
- Spring Boot 面试杀手锏:自动配置原理
- Java 11正式发布,新特性解读
- cascader 动态加载 回显_Element中的Cascader(级联列表)动态加载省\市\区数据的方法...
- spring14:注解@Autowired,实现引用类型的赋值
- redis-查看日志
- C#反射技术在多语言实现中的实际用处参考,让初学者学技术有个针对性【附源码】...
- 2个 string 日期比较
- pythonweb好难-(2017)我不建议使用的Python Web框架
- UE3 GPU性能和分析
- html清除div浮动,HTML_清除浮动的最优方法:CSS,在CSS森林群里讨论一个margin的 - phpStudy...
- node html响应头,nodejs 中http请求头,响应头
- 有N个软件包未被升级
- Postman下载与安装操作步骤(只有两步骤下载)
- 网站统计系统内容分析
- oracle 70个常用函数
- 程序员效率:整理常用的在线笔记软件
- 软件学院“SIdea”软件创意大赛
- 【解决】Expanding invalid MinMaxAABB
- NFT Insider #60:电讯盈科联同香港电讯进驻 The Sandbox,BreederDAO 团队登上《福布斯》封面
- ddmmyy日期格式是多少_英语中关于年月日以及数字