内存溢出 out of memory
是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
内存溢出就是你要求分配的内存超出了系统能给你的,系统不能满足需求,于是产生溢出。
内存泄露 memory leak
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete)
memory leak积累到一定程度最终会导致out of memory!
Java没有直接操作内存的能力,内存管理由底层GC自动完成,造成Android应用内存泄露的主要原因是:
持有大量无用或重复对象,无法被底层GC识别为垃圾对象,以至于无法将其回收。
Android(Java)中常见的容易引起内存泄漏
Java虽然有自己的垃圾回收机制,但其不是实时进行的,而且Android底层给每个应用分配的内存空间是有限的,如果使用不当,很容易由于内存泄露回收不及时,造成OOM.
1. 查询数据库没有关闭游标Cursor,在操作大量数据之后,产生内存泄露。
2. ListView加载大量数据,没有复用ConvertView,生成大量新对象。
3. 使用了大的Bitmap之后,没有调用recycle()方法,内存一直被占用。
4. 持有大量无用对象的引用,例如使用static对象,对象生命周期很长,会一直存在,建议使用软引用的形式。
注册监听器,退出时没有取消注册。
5. Activity 退出之后,依然有没有退出的线程在执行,比如循环刷新界面的线程,造成Activity的资源不被回收。
检测内存泄露
Android tools中的DDMS就带有一个很不错的内存监测工具Heap
Heap视图中部有一个Type叫做data
object,即数据对象,也就是我们的程序中大量存在的类类型的对象。在data object一行中有一列是“Total Size”,其值就是当前进程中所有Java数据对象的内存总量,一般情况下,这个值的大小决定了是否会有内存泄漏。
正常情况下Total
Size值都会稳定在一个有限的范围内,也就是说由于程序中的的代码良好,没有造成对象不被垃圾回收的情况,所以说虽然我们不断的操作会不断的生成很多对 象,而在虚拟机不断的进行GC的过程中,这些对象都被回收了,内存占用量会会落到一个稳定的水平;
反之如果代码中存在没有释放对象引用的情况,则data object的Total Size值在每次GC后不会有明显的回落,随着操作次数的增多Total Size的值会越来越大,直到到达一个上限后导致进程被kill掉。