工具选择
- Memory Profiler
- Memory Analyzer(MAT)
- LeakCanary
Java内存管理机制
标记-清除算法(Mark-Sweep GC)
标记可回收的内存块,直接对其进行回收。
优点:效率快
缺点:内存空洞比较多

复制算法(Copying GC)
把所有内存一份为二,可使用内存占其中一半,进行回收时,把可用内存块搬移到另一半内存中。
优点:解决了内存空洞
缺点:无法充分使用内存,永远只能使用一半内存

标记-整理算法 或 标记-压缩算法(Mark-Compact GC)
结合了标记-清理算法和复制算法的思想。
标记过程与“标记-清理算法”一样
标记的内存块进行回收后,存活内存块进行整理
最后清理内存

分代收集算法
结合了上述的多种收集算法
把内存块进行了分类,分“新生代”和“老年代”
存活周期短的内存块,划分为“新生代”,直接使用“复制算法”进行回收
存活周期长的内存块,划分为“老年代”,使用“标记-整理算法”
针对分代收集的具体资料:
Java虚拟机:垃圾收集算法 - 方志朋的博客
Java Garbage Collection Basics
《深入理解java虚拟机》笔记2——GC算法与内存分配策略 | Joker’s Blog | 个人分享博客
Android中的内存管理机制
内存弹性分配,分配值与最大值受具体设备影响。
app打开时内存分配不是固定额度,而是根据app需要的内存进行分配,可大可小。然而这个分配值也依据不同设备受到影响。比如2G内存的手机和4G内存手机,它们的分配值和最大值就不相同。
OOM场景:内存真正不足和可用内存不足
outOfMemory异常需要区分场景。
- 内存真正不足:假设当前设备可给app分配的最大内存是256m,而此时app已经使用了250m,当app在申请需要10m内存时,超过了可分配的内存,则报oom错误
- 可用内存不足:假设当前设备的内存已经完全用完,再没有更多空间可以分配,而我们的app又去申请内存,也会报oom错误。这种情况,完全是内存耗尽,受运行整体环境而定。
这两个场景需要区分一下。
Dalvik和Art区别
-
Dalvik使用什么算法,是在编译期决定的。
如果编译指令指定“WITH_COPYING_GC”,则使用“复制算法”,否则使用“标记-清理算法”。所以,Dalvik始终只有一个回收算法。 -
Art使用什么算法,可以在运行时决定。
即,当app运行在前台时,这时响应性是很重要的,所以使用效率高的“标记-清除算法”(Foreground GC)。
当app运行在了后台,响应性就不是那么重要了,可以慢慢清理,同时整理一下内存块,就可以使用“标记-整理算法”(Background GC)
针对Dalvik和Art的GC具体资料:
Android GC原理探究 - 知乎
Low Memory Killer
- 进程分类:前台进程,可见进程,服务进程,后台进程,空进程
- 前台进程
与用户正在交互的Activity或者Activity用到的Service等,如果系统内存不足时前台进程是最后被杀死的。 - 可见进程
处于暂停状态(onPause)的Activity或者绑定在其上的Service,即被用户 可见,但由于失去了焦点而不能与用户交互。例如:Activity弹出一个dialog,当前的Activity就是可见进程 - 服务进程
其中运行着使用startService方法启动的Service,虽然不被用户可见,但是却是用户关心的,例如用户正在非音乐界面听的音乐或者正在非下载页面自己下载的文件等;当系统需要空间运行前两者进程(–>指的是前台进程和可见进程)时才会被终止. - 后台进程
运行着执行onStop方法而停止的程序,但是却不是用户当前关心的,例如后台挂着的QQ,这样的进程系统一旦没了有内存就首先被杀死. - 空进程
不包含任何应用程序的程序组件的进程,这样的进程系统是一般不会让他存在的,为了进行缓存,使下次App启动的时候更快,当系统需要内存是最先被杀死。
- 前台进程
系统会根据进程等级,优先回收低等级进程。
- 回收收益
视情况回收内存,可大可小。
网友评论