Android内存泄漏相关与Lru概念
一.Java内存泄漏基本知识
1.Java内存的分配策略(静态分配,践式分配,堆式分配)
1)静态存储区(方法区):存放静态数据和一些全局变量
2)栈区(方法里的局部变量会在这里创建内存空间,方法结束后会被自动释放)
3)堆区:动态内存分配,通常是我们new对象或者集合数组,不用的时候由GC回收
2.Java是如何管理内存的
Java的内存管理其实主是对象分配和释放问题,比如我们new对象的时候就会向内存申请内存空间,对象的释放是由垃圾回收机制完成的.内存分配由我们开发人员来完成,回收由GC自动完成.
3.Java中的内存泄漏
无用对象或不再使用的对象持续占有内存,而得不到及时的释放,从而造成的内存空间的浪费 .
二.Android中的内存泄漏
1.单例:单例的静态特性使得它的生命周期和App应用的生命周期一样长.
所以一个对象不在需要使用,而这个单例还持有了这个对象引用.想要释放的对象得不到回收. 比如Activity的Context
2.匿名内部类:非静态内部类会持有外部类引用,而使用了该内部类里面的创建了一个静态实例的话,这个静态实例和App应用一样长,导致了这个静态实例一直持有该Activity实例得不到回收.
3.handler: 非静态handler会持有外部类的引用,handler的消息队列是在Lopper线程中不断的轮循处理消息,当这个外部类要退出时,消息队列中还有未处理的消息或正在处理的消息,而消息中的message又持有了该Activity的引用.从而导致这个外部类不能被回收.
解决方法
static class MyHandler extends Handler {
WeakReference<Activity> mWeakReference;
public MyHandler(Activity activity) {
mWeakReference = new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg) {
final Activity activity = mWeakReference.get();
if (activity != null) {
if (msg.what == 1) {
//做一些操作
}
}
}
}
4.避免使用static变量
5.资源没有关闭 file bitmap curson io
三.LRU:内部是由一个LinkHashMap来实现的,里面提供给我们put get方法来完成添加和获取操作,当缓存满了的时候会提供一个trimToSize方法将不常使用的对象删除并添加新的对象.
public void trimToSize(int maxSize) {
while (true) {
K key;
V value;
synchronized (this) {
if (size < 0 || (map.isEmpty() && size != 0)) {
throw new IllegalStateException(getClass().getName()
+ ".sizeOf() is reporting inconsistent results!");
}
if (size <= maxSize) {
break;
}
Map.Entry<K, V> toEvict = map.eldest();
if (toEvict == null) {
break;
}
key = toEvict.getKey();
value = toEvict.getValue();
map.remove(key);
size -= safeSizeOf(key, value);
evictionCount++;
}
entryRemoved(true, key, value, null);
}
}
上一篇: 内存泄漏