Android内存泄露总结(附内存检测工具)内存泄露总结(附内存检测工具)
Java 中的内存分配
主要是分三块:
静态储存区:编译时就分配好,在程序整个运行期间都存在。它主要存放静态数据和常量。
栈区:当方法执行时,会在栈区内存中创建方法体内部的局部变量,方法结束后自动释放内存。
堆区:通常存放 new 出来的对象。由 Java 垃圾回收器回收。
栈与堆的区别
栈内存用来存放局部变量和函数参数等。它是先进后出的队列,进出一一对应,不产生碎片,运行效率稳定高。当超
过变量的作用域后,该变量也就无效了,分配给它的内存空间也将被释放掉,该内存空间可以被重新使用。
堆内存用于存放对象实例。在堆中分配的内存,将由Java垃圾回收器来自动管理。在堆内存中频繁的 new/delete 会造
成大量内存碎片,使程序效率降低。
对于非静态变量的储存位置,我们可以粗暴的认为:
局部变量位于栈中(其中引用变量指向的对象实体存在于堆中)。
成员变量位于堆中。因为它们属于类,该类最终被new成对象,并作为一个整体储存在堆中。
四种引用类型的介绍
GC 释放对象的根本原则是该对象不再被引用(强引用)。那么什么是强引用呢?
强引用(Strong Reference)
我们平常用的最多的就是强引用,如下:
IPhotos iPhotos = new IPhotos();
JVM 宁可抛出 OOM ,也不会让 GC 回收具有强引用的对象。强引用不使用时,可以通过 obj = null 来显式的设置该对
象的所有引用为 null,这样就可以回收该对象了。至于什么时候回收,取决于 GC 的算法,这里不做深究。
软引用(Soft Reference)
SoftReference<String> softReference = new SoftReference<>(str);
如果一个对象只具有软引用,那么在内存空间足够时,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些
对象的内存。只要垃圾回收器没有回收它,该对象就可以被使用。
软引用曾经常被用来作图片缓存,然而谷歌现在推荐用 LruCache 替代,因为 LRU 更高效。
In the past, a popular memory cache implementation was a SoftReference
or WeakReference bitmap cache, however this is not recommended.
Starting from Android 2.3 (API Level 9) the garbage collector is more
aggressive with collecting soft/weak references which makes them