http://www.jianshu.com/p/402225fce4b2
内存泄露:
当一个对象已经不在使用了,本该被回收时,而有另外一个正在使用的对象持有它的引用,从而导致了对象不能被GC所回收。这种导致了本该被回收的对象不能被回收而停留在堆内存中,就产生了内存泄露。
内存溢出:
当应用的heap资源超出了Dalvik虚拟机分配的内存就会溢出。
Android为每个进程设置Dalvik Heap Size阈值,这个阈值在不同的设备上会因为RAM大小不同而各有差异。如果APP想要分配的内存超过这个阈值,就会发生OOM。
ActivityManager.getMemoryClass()可以查询当前APP的Heap Size阈值,单位是MB。
内存泄露带来的影响:
应用卡顿
泄露的内存影响了GC的内存分配,过多的内存泄露会影响应用的执行效率。
应用异常(OOM)
过多的内存泄露,最终会导致Dalvik分配的内存,出现OOM
JVM内存管理
java采用GC进行内存管理。JVM内存分配的几种策略:
1、静态的
静态的存储区,内存在程序编译的时候就已经分配好了,这块内存在程序整个运行期间都一直存在,它主要存放静态数据、全局的static数据以及一些常量。
2、栈式的
在执行方法时,方法一些内部变量的存储都可以放在栈上面创建,方法执行结束的时候,这些存储单元格就会自动被注释掉。栈内存包括分配的运算速度很快,因为内在在处理器里面。当然容量有限,并且栈式一块连续的内存区域,大小是由操作系统决定的,他先进后出,进出完成不会产生碎片,运行效率高且稳定
3、堆式的
也叫动态内存
我们通常使用new来申请分配一个内存。GC会根据内存的使用情况,对堆内存里垃圾内存进行回收。堆内存是一块不连续的内存区域,如果频繁的new/remove会造成大量的内存碎片,GC频繁的回收,导致内存抖动,消耗应用性能。
可以使用一些标记来让GC更好的对内存进行回收:
StrongReference (强引用)
任何时候GC是不能回收他的,哪怕内存不足时,系统会直接抛出异常OutOfMemoryError,也不会去回收
进程终止
SoftReference (软引用)当内存足够时不会回收这种引用类型的对象,只有当内存不够用时才会回收
内存不足,进行GC的时候
WeakReference (弱引用)GC一运行就会把给回收了GC后终止
PhantomReference (虚引用)
如果一个对象与虚引用关联,则跟没有引用与之关联一样,在任何时候都可能被垃圾回收器回收
任何时候都有可能