内存泄漏ML
内存溢出OOM
CPU只能访问寄存器和内存,存储在硬盘的文件要先放到内存,才能被CPU访问。
访问速度快到慢:寄存器 内存 硬盘
程序加载在内存中由四个区域组成
- 堆栈(stack):栈是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
- 堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
- 代码段(code)
- 数据段(data):数据段用来存放可执行文件中已初始化全局变量,换句话说就是存放程序静态分配变量和全局变量
- BSS:程序中未初始化的全局变量,内存中全部是0
内存回收机制
退出不关闭:退出APP后,不关闭,还占用内存,下次使用快速响应。后台应用只耗内存,不占用CPU,不耗电,不影响速度。
当系统内存不足,内存回收有一个阈值,只有低于这个值时会激活内存回收机制。
内存回收优先级
- 前台进程:IMPORTANCE_FOREGROUND 在屏幕上显示的进程以及系统进程
- 可见进程:IMPORTANCE_VISIBLE 不在前台,但是依然可见,时间 天气 输入法,这部分进程虽然不在前台,但与我们的使用也密切相关,我们也不希望它们被终止
- 服务进程:IMPORTANCE_SERVICE 拨号 邮件
- 后台进程:IMPORTANCE_BACKGROUND 启动后切换到后台
- 空进程:IMPORTANCE_EMPTY 程序退出后,没有任何数据在运行,只是为了提升下次启动速度
oom_adj用来存放系统对进程重要性的评估,系统根据这个值来选择结束哪个进程,数值越大被结束的可能性越大,前台进程为0。
内存少时运行大型程序慢是因为在内存剩余不多时打开大型程序时会触发系统自身的调进程调度策略。
Dalvik虚拟机为每个APP分配相应的内存,有一个数值范围。Android系统会将在后台运行的App进程保存在一个LRU cache中。当系统内存紧张时,它会根据LRU的策略kill掉一些优先级比较低的进程。
LRU cache :替换掉一段时间内最久没被使用过的进程,利用hashmap+双向链表构成。
- 双向链表用来存储数据节点,被调用的进程放到表头,内存不够时释放表尾结点。 如果一个结点被访问了,
我们有理由相信它在接下来的一段时间被访问的概率要大于其它结点。 - hashmap是为了查找节点时节省时间,降低时间复杂度