内存泄露
Java内存泄漏指的是进程中某些对象(垃圾对象)已经没有使用价值了,但是它们却可以直接或间接地引用到gc
roots导致无法被GC回收。无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏了。下面分析一些可能导致内存泄漏的情景。
- 非静态内部类的静态实例容易造成内存泄漏
- activity使用静态成员
- handler
非静态 - 注册某个对象后未反注册
- 资源对象没关闭造成的内存泄露
- 构造Adapter时,没有使用缓存的 convertView
以上分析只是常见的问题,本质上是
*
全局进程(process-global)的static变量。这个无视应用的状态,持有Activity的强引用的怪物
* 活在Activity生命周期之外的线程。没有清空对Activity的强引用
可以参考下面文章的讲解及解决方式。本文重点是关注handler这类非静态引起及使用WeakReference
, SoftReference
来处理。
引例
先看 下面代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
Activity的销毁会到10分钟后的handler执行完毕。解决办法其实有比较多的方案,这里使用WeakReference
解决方案
- 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
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
这样一来Activity不再是handler的强引用了,对于重度Activity类如此来解决还是比较好的。
在Finally understanding how references work in Android and
Java讲到了WeakReference
,SoftReference
,PhantomReference
,Strong reference
.一般SoftReference
更适合做Cache,在系统内存不足时才会清理。
Strong
reference: strong references are
the ordinary references in Java. Anytime we create a new object, a strong
reference is by default created.WeakReference:
a weak reference is a reference not strong enough to keep the object in memory.
If we try to determine if the object is strongly referenced and it happened to
be through WeakReferences, the object will be garbage-collected.SoftReference:
think of a SoftReference as a stronger WeakReference. Whereas a WeakReference
will be collected immediately, a SoftReference will beg to the GC to stay in
memory unless there is no other option. The Garbage Collector algorithms are
really thrilling and something you can dive in for hours and hours without
getting tired. But basically, they say “I will always reclaim the WeakReference.
If the object is a SoftReference, I will decide what to do based on the
ecosystem conditions”. This makes a SoftReference very useful for the
implementation of a cache: as long as the memory is plenty, we do not have to
worry of manually removing objects.PhantomReference:
Ah, PhantomReferences! I think I can count on the fingers of one hand how often
I saw them used in a production environment. An Object that has only being
referenced through a PhantomReference them can be collected whenever the Garbage
Collector wants. No further explanations, no “call me back”. This makes it hard
to characterise. Why would we like to use such a thing? Are the other ones not
problematic enough? Why did I choose to be a programmer? PhantomReference can be
used exactly to detect when an object has been removed from memory. Being fully
transparent, I recall two occasions when I had to use a PhantomReference in my
entire professional career. So do not get stressed if they are hard to
understand now.