性能优化-内存泄露常见例子
之前说了内存泄漏和检测工具,这里就记录一下常见的内存泄露有哪些
前言
在举例子以前,需要明白两个概念
- 内存泄露(
Memory Leak
):某些对象已经不再使用,但仍然直接或间接的被引用到GC ROOT
中,此时GC没法对其进行回收,就造成了内存泄露 - 内存溢出(
OOM
):当应用占用了大于虚拟机分配的内存空间时,会造成内存溢出
静态变量引起的内存泄露
当调用getInstance
时,如果传入的context
是Activity
的context
。只要这个单利没有被释放,那么这个Activity
也不会被释放一直到进程退出才会释放
public class CommUtil {private static CommUtil instance;private Context context;private CommUtil(Context context){this.context = context;}public static CommUtil getInstance(Context mcontext){if(instance == null){instance = new CommUtil(mcontext);}return instance;}
}
非静态内部类引起内存泄露(包括匿名内部类)
错误的示范:
public void loadData(){new Thread(new Runnable() {@Overridepublic void run() {while(true){try {//处理数据} catch (InterruptedException e) {e.printStackTrace();}}}}).start();
}
当调用这个方法的时候,这个内部类会持有调用方法的类,可能就会造成内存泄露
解决方案:将非静态内部类修改为静态内部类(静态内部类不会隐式持有外部类)
public static void loadData(){new Thread(new Runnable() {@Overridepublic void run() {while(true){try {//处理数据} catch (InterruptedException e) {e.printStackTrace();}}}}).start();
}
其实就是非静态方法的生命周期短于当前类而造成的内存泄露
还有另一种情况,线程延迟执行的情况,此时已经加载到执行队列,比如:
public static void loadData(){new Timer().schedule(new TimerTask() {@Overridepublic void run() {while(true){try {//处理数据} catch (InterruptedException e) {e.printStackTrace();}}}}, 20000);
}
那么这种情况就需要在onDestroy
方法中把timer.cancel
掉然后赋空
在使用Handler
时候也存在这样的情况,例如
private Handler mHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what){case 0://处理数据break;}}
};
如果在其外部调用mHandler.sendEmptyMessage(0);
或者mHandler.sendMessageAtTime(msg,10000);
方法的时候,此时mHandler
作为内部类,持有外部类的引用,如果其Activity
退出,那么mHandler
可能还存在,那么此时就会一直持有Activity
,就造成了内存泄露
解决办法:
- 与其他处理方式一样,将其设置为静态内部类
- 如果在其内部需要使用外部类的资源时,将
Handler
设置为弱引用
private static class MyHandler extends Handler{//private MainActivity mainActivity;//直接持有了一个外部类的强引用,会内存泄露private WeakReference<MainActivity> mainActivity;//设置弱引用保存,当内存一发生GC的时候就会回收public MyHandler(MainActivity mainActivity) {this.mainActivity = new WeakReference<MainActivity>(mainActivity);}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);MainActivity main = mainActivity.get();if(main == null || main.isFinishing()){return;}switch (msg.what){case 0://处理数据int b = main.a; //引用外部类的资源break;}}
}
不需要用的监听未移除会发生内存泄露
例子1:
final TextView tv = (TextView) findViewById(R.id.tv);
tv.setOnClickListener(); //监听执行完回收对象
tv.getViewTreeObserver().addOnWindowFocusChangeListener(new ViewTreeObserver.OnWindowFocusChangeListener() {@Overridepublic void onWindowFocusChanged(boolean b) {//监听处理,处理完成后要移除监听tv.getViewTreeObserver().removeOnWindowFocusChangeListener(this);}
});
如果要设计ListenerCollector
,那么一般使用WeakHashMap
,WeakHashMap
除了自身有对key的引用外,此key没有其他引用那么此map会自动丢弃此值
public class ListenerCollector {static private WeakHashMap<View, MyView.MyListener> sListener = new WeakHashMap<>();public void setsListener(View view, MyView.MyListener listener) {sListener.put(view, listener);}public static void clearListeners() {//移除所有监听sListener.clear();}
例子2:
SensorManager sensorManager = getSystemService(SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ALL);
sensorManager.registerListener(this,sensor,SensorManager.SENSOR_DELAY_FASTEST);
//不需要用的时候移除监听
sensorManager.unregisterListener(listener);
资源未关闭引起的内存泄露情况
BroadCastReceiver
、Cursor
、Bitmap
、IO流
、自定义属性attribute
等
当不需要使用的时候,及时释放资源,否则就会内存泄露
无限循环动画
没有在onDestroy
中停止动画,否则Activity
就会变成泄露对象,比如:轮播图效果
转载于:https://www.cnblogs.com/cj5785/p/10664640.html
性能优化-内存泄露常见例子相关推荐
- Android性能优化(2):常见内存泄漏与优化(二)
文章目录 1. Android虚拟机:Dalvik和ART 1.1 JVM与Dalvik区别 1.2 Dalvik与ART区别 1.3 Dalvik/ART的启动流程 2. 常见内存分析工具 2.1 ...
- Android性能优化 - 内存优化
性能优化系列阅读 Android性能优化 性能优化 - 消除卡顿 性能优化- 内存优化 性能分析工具 - TraceView Android性能分析工具 为什么内存优化? 在一个商业项目中,很有可能因 ...
- SQL性能优化技巧,常见优化10经验,数据库查询好慢,还能怎么办
我熟练应用ctrl c和ctrl v 开发curd代码好多年了. mysql查询为什么会慢,关于这个问题,在实际开发经常会遇到,而面试中,也是个高频题. 遇到这种问题,我们一般也会想到是因为索引. 那 ...
- Unity移动端游戏性能优化简谱之 常见游戏内存控制
<Unity移动端游戏性能优化简谱>从Unity移动端游戏优化的一些基础讨论出发,例举和分析了近几年基于Unity开发的移动端游戏项目中最为常见的部分性能问题,并展示了如何使用UWA的性能 ...
- ios 内存深度优化_iOS 25个性能优化/内存优化常用方法
用ARC管理内存 ARC(Automatic ReferenceCounting, 自动引用计数)和iOS5一起发布,它避免了最常见的也就是经常是由于我们忘记释放内存所造成的内存泄露.它自动为你管理r ...
- Linux性能优化—内存实战篇
一.Linux内存工作原理 相关视频讲解: 深入讲解Linux内核内存管理(第一节) 深入讲解Linux内核内存管理( 第二节) Linux内核源码/内存调优/文件系统/进程管理/设备驱动/网络协议栈 ...
- iOS性能优化-内存优化(1)
1.iOS的内存管理机制 Objective-C语言本身是支持垃圾回收机制的,但有平台局限性,仅限于Mac桌面系统开发中. 而在iPhone和iPad等苹果移动终端设备中是不支持垃圾回收机制的.在移动 ...
- iOS性能优化-内存优化
https://blog.csdn.net/a184251289/article/details/82589128 2018年09月10日 14:25:31 xingshao1990 阅读数:328 ...
- java 内存泄漏场景_Java内存泄露的例子
在定位JVM性能问题时可能会遇到内存泄露导致JVM OutOfMemory的情况,在使用Tomcat容器时如果设置了reloadable="true"这个参数,在频繁热部署应用时也 ...
- sqlite事务模型、性能优化tips、常见误区
0,前言 本文主要介绍sqlite的事务模型,以及基于事务模型的一些性能优化tips,包括事务封装.WAL+读写分离.分库分表.page size优化等.并基于手淘sqlite的使用现状总结了部分常见 ...
最新文章
- aes js 加盐值 解密_crypto-js aes加密解密
- NB-IOT来了,物联网时代才真正来临
- 通过RS232发送和接收短信(二)
- Core官方DI解析(2)-ServiceProvider
- 前端技术-调试工具(上)
- C# 是否可以将 动态或匿名类型 转成 强类型 ?
- 设计模式(七)装饰模式
- Ubuntu 新建qt项目时出现 No valid kits found.
- 蓝筹股、红筹股的含义
- 计算机0812是学硕还是专硕,的计算机是专硕还是学硕
- ubuntu16 下安装freeswitch 1.8.3
- java局域网发送文件_Java如何实现局域网文件传输代码案例分享
- VLC帮助文档-中文详细版(vlc-2.2.6)
- 使用思博伦Spirent TsetCenter测试RFC 2544(1)_开始 _双极未来
- VS2008编译的程序在某些机器上运行提示“由于应用程序配置不正确,应用程序未能启动”的问题
- 风景照片转水彩画效果PS动作
- DNK基础之静态库、动态库、编译流程
- shell学习笔记:变量篇
- 这些两轮电动车的黑科技你知道吗?
- Django 入门教程