android的内存泄露有几种,Android中几种有可能会导致内存泄露的情况
8种机械键盘轴体对比
本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?
1.Static静态成员导致的内存泄露
将占用大量内存空间的变量声明为static静态类型。当Activity被销毁的时候,由于静态成员的缘故,所占用的内存空间并没有得到及时的释放,最终导致内存泄漏。所以不要在静态空间中放太大的资源,如果一定要放,需要在结束的时候对其进行释放和清理。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21public class MainActivity extends Activity {
private static final int ARRAY_SIZE = 100;
private static Drawable[] sTestBitmap = new Drawable[ARRAY_SIZE];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
for (int i = 0 ; i < ARRAY_SIZE ; i++) {
sTestBitmap[i] = getResources().getDrawable(R.drawable.test);
}
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
super.onDestroy();
/*for (int i = 0 ; i < ARRAY_SIZE ; i++) {
sTestBitmap[i] = null;
}
sTestBitmap = null;
System.gc();*/
}
}
2.匿名内部类的使用 每一个匿名内部类都持有一个外部类的引用,当我们如果在一个匿名类中启动一个线程,那么它将一直持有外部类的引用,直到线程结束才能将内存空间释放。当我们在MainActivity中启动一个线程,虽然退出了该Activity,但是进程还在运行,MainActivity所占用的内存空间将得不到释放,导致最后的内存泄漏1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23public class MainActivity extends Activity {
private Drawable mTestBitmap = null;
private Thread mThread = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mThread = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
}
}
});
mThread.start();
mTestBitmap = getResources().getDrawable(R.drawable.test);
setContentView(R.layout.activity_main);
}
@Override
protected void onDestroy() {
super.onDestroy();
//TODO cancel Thread
}
}
3.Context的滥用1
2
3
4
5
6
7
8
9
10
11
12
13
14private static Drawable sBackground;
@Override
protected void onCreate(Bundle state){
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
}
在这种情况下,Drawble持有Textiview的引用,TextView持有Activity的引用,即使Activity被销毁,内存仍然不会被释放。 若Context的引用超过其本身生命周期,也会导致内存泄漏,一般用getApplicationContext即可 使用Application这种Context类型 对Context的引用不要超过其自身生命周期 慎重使用Static关键字 context里如果有限程,一定在onDestroy中结束掉 4.在Handler中遇到的问题 当使用内部类创建Handler的时候,Handler会持有一个外部Activity的引用。当Handler中的线程在执行的时候,Activity被GC,这时该线程持有Handler的引用,Handler含有Activity的引用,导致该Activity无法被回收,导致内存泄漏 解决办法: 1.通过程序逻辑来判断,在关闭Activity的同时停止线程,Activity就可以正常在合适的时候被回收。如果Handler是被delay的Message持有了引用,那么使用相应的Handler的removeCallbacks()方法,把消息对象从消息队列移除就行了 2.将Handler声明为静态类,不再持有外部类的引用,所以Activity可以被回收。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34public class MainActivity extends Activity {
private final int MSG_DO_SOMETHING = 0;
private SafeHandler mHandler = new SafeHandler(this);
private TextView mTextView = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mTextView = new TextView(this);
Message.obtain(mHandler, MSG_DO_SOMETHING).sendToTarget();
mHandler.sendMessageDelayed(Message.obtain(mHandler, MSG_DO_SOMETHING), 1000);
setContentView(R.layout.activity_main);
}
static class SafeHandler extends Handler {
WeakReference mActivityReference;
SafeHandler(MainActivity activity) {
mActivityReference= new WeakReference(activity);
}
@Override
public void handleMessage(Message msg) {
final MainActivity activity = mActivityReference.get();
if (activity != null) {
activity.mTextView.setTextColor(Color.WHITE);
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
//删除所有Message
mHandler.removeMessages(MSG_DO_SOMETHING, null);
//删除Message.what==MSG_DO_SOMETHING的Message
mHandler.removeMessages(MSG_DO_SOMETHING);
}
}
总结:
不要让生命周期长于Activity的对象持有到Activity的引用
尽量使用Application的Context而不是Activity的Context
尽量不要在Activity中使用非静态内部类,因为非静态内部类会隐式持有外部类实例的引用(具体可以查看 细话Java:”失效”的private修饰符 了解)。如果使用静态内部类,将外部实例引用作为弱引用持有。
垃圾回收不能解决内存泄露,了解 Android中垃圾回收机制
android的内存泄露有几种,Android中几种有可能会导致内存泄露的情况相关推荐
- 使用ThreadLocal不当可能会导致内存泄露
使用ThreadLocal不当可能会导致内存泄露 基础篇已经讲解了ThreadLocal的原理,本节着重来讲解下使用ThreadLocal会导致内存泄露的原因,并讲解使用ThreadLocal导致内存 ...
- kera中使用keras.banked.ctc_decoder()导致内存不断增加的问题解决
kera中使用keras.banked.ctc_decoder()导致内存不断增加的问题解决 遇到的问题 在使用keras训练了模型后,使用模型进行测试,测试过程中发现随着测试数据的增加,测试速度不断 ...
- android开发中,可能会导致内存泄露的问题
转自 : http://spencer-dev.lofter.com/post/d7b9e_6faf120 在android编码中,会有一些简便的写法和编码习惯,会导致我们的代码有很多内存泄露的问题. ...
- android 集合 内存泄漏,Android内存泄漏第二课--------(集合中对象没清理造成的内存泄漏 )...
一.我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大.如果这个集合是static的话,那情况就更严重 ...
- 7种可能会导致内存泄漏的场景!
虽然Java程序员不用像C/C++程序员那样时刻关注内存的使用情况,JVM会帮我们处理好这些,但并不是说有了GC就可以高枕无忧,内存泄露相关的问题一般在测试的时候很难发现,一旦上线流量起来可能马上就是 ...
- keilcjson内存分配失败_iOS标准库中常用数据结构和算法之内存池
黑客技术点击右侧关注,了解黑客的世界! Java开发进阶点击右侧关注,掌握进阶之路! Linux编程点击右侧关注,免费入门到精通! 作者丨欧阳大哥2013https://www.jianshu.com ...
- java 死锁 内存消耗_详解Java中synchronized关键字的死锁和内存占用问题
先看一段synchronized 的详解: synchronized 是 java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并 ...
- aix oracle 内存限制,请教 AIX 与 Linux 中,怎样分析Oracle的内存占用?
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 列出如下脚本对应输出: ps vg|grep ora|awk '{sum=sum+$7-$10} END {print sum/1024}' svmon ...
- python导入模块有几种_Python中几种导入模块的方式总结
模块内部封装了很多实用的功能,有时在模块外部调用就需要将其导入.常见的方式有如下几种: 1 . import >>> import sys >>> sys.path ...
最新文章
- ENJOYLink欢联,以独创技术满足数据中心布线
- diskgenius扩容c盘重启电脑卡住_电脑使用DiskGenius工具增加C盘空间的方法
- 0326互联网新闻 | 字节跳动推出阅读产品番茄小说;微信正式上线物流助手接口功能...
- mysql ERROR 1045 (28000): Access denied for user解决方法
- clamav程序的研究总结
- 前端学习(2736):重读vue电商网站46之执行build 时报错
- Elasticsearch7.15.2 报java.lang.NoClassDefFoundError: org/elasticsearch/client/Cancellable的解决方案
- 上万规模数据湖如何在实验室测试
- 蓝牙nrf52832的架构和开发(转载)
- 重大发现: windows下C++ UI库 UI神器-SOUI(转载)
- hdfs的实验总结_HDFS原理及操作
- CDH6离线安装教程
- 货运APP系统开发搭建一步到位
- 游戏开发中的物理之软体
- UVa 10696 - f91
- java异常之-Caused by: java.lang.IllegalStateException: Method has too many Body parameters
- MATLAB图中图绘制(局部放大图)
- 计算机网络系统的维护,简论事业单位计算机网络管理系统的维护
- 编程练习:MP3播放器
- 显卡超频很简单 RivaTuner使用教程