android内存机制_安卓手机内存怎样清理最彻底

Android (3) 2024-09-23 21:23

Hi,大家好,我是编程小6,很荣幸遇见你,我把这些年在开发过程中遇到的问题或想法写出来,今天说一说
android内存机制_安卓手机内存怎样清理最彻底,希望能够帮助你!!!。

何为内存?

android内存机制_安卓手机内存怎样清理最彻底_https://bianchenghao6.com/blog_Android_第1张

内存是计算机中重要的部件之一,它是与 CPU 进行沟通的桥梁;内存(Memory)也称为内存储器,其作用是用于暂时存放 CPU 中的运算数据,以及与硬盘等外部存储器交换的数据;只要计算机在运行中,CPU 就会把需要运算的数据调到内存中进行运算,当运算完成后,CPU 再将结果传送出来,内存的运行也决定了计算机的稳定运行

Android 属于 Linux 系统

现象: Linux 经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面是内存不足,实际是 Linux 内存管理的优秀特性

特点: 无论物理内存多大,Linux 都将其充分利用,缓存到内存提高性能,充分发挥硬件投资带来的好处

而 window 的内存管理,只在需要内存时,才为应用分配内存,不能充分利用,硬件投资相当于摆设

Android 每一个应用都带有独立的虚拟机,回收机制

Android对内存的使用方式是“尽最大限度的使用”,只有当内存水足的时候,才会杀死其它进程来回收足够的内存; 但Android系统否可能随便的杀死一个进程,它也有一个机制杀死进程来回收内存

Android杀死进程

进程优先级

Android为每一个进程分配了优先组的概念,优先组越低的进程,被杀死的概率就越大;根据进程的重要性,划分为5级:

前台进程(Foreground process)

用户当前操作所必需的进程。通常在任意给定时间前台进程都为数不多。只有在内存不足以支持它们同时继续运行这一万不得已的情况下,系统才会终止它们

可见进程(Visible process)

没有任何前台组件、但仍会影响用户在屏幕上所见内容的进程。可见进程被视为是极其重要的进程,除非为了维持所有前台进程同时运行而必须终止,否则系统不会终止这些进程。

服务进程(Service process)

尽管服务进程与用户所见内容没有直接关联,但是它们通常在执行一些用户关心的操作(例如,在后台播放音乐或从网络下载数据)。因此,除非内存不足以维持所有前台进程和可见进程同时运行,否则系统会让服务进程保持运行状态。

后台进程(Background process)

后台进程对用户体验没有直接影响,系统可能随时终止它们,以回收内存供前台进程、可见进程或服务进程使用。 通常会有很多后台进程在运行,因此它们会保存在 LRU 列表中,以确保包含用户最近查看的 Activity 的进程最后一个被终止

如果某个 Activity 正确实现了生命周期方法,并保存了其当前状态,则终止其进程不会对用户体验产生明显影响,因为当用户导航回该 Activity 时,Activity 会恢复其所有可见状态

空进程(Empty process)

不含任何活动应用组件的进程,保留这种进程的的唯一目的是用作缓存,以缩短下次在其中运行组件所需的启动时间; 为使总体系统资源在进程缓存和底层内核缓存之间保持平衡,系统往往会终止这些进程

通常,前面三种进程不会被杀死

内存调度有个阈值,当剩余内存低于这个值,系统才会根据策略关闭用户不需要的东西;当这个阈值很小时,内存总会在此值徘徊,但事实上不影响速度,相反加快了下次启动速度

这种设计,下次启动应用会更快,因为不需要读取界面资源,所以用户平时不用习惯一键清理抹杀掉安卓这个优点

Android对内存的使用方式

Android对内存的使用方式同样是“尽最大限度的使用”,这一点继承了Linux的优点;只不过有所不同的是,Linux侧重于尽可能多的缓存磁盘数据以降低磁盘IO进而提高系统的数据访问性能,而 Android侧重于尽可能多的缓存进程以提高应用启动和切换速度;Linux系统在进程活动停止后就结束该进程,而Android系统则会在内存中尽量长时间的保持应用进程,直到系统需要更多内存为止

这些保留在内存中的进程,通常情况下不会影响系统整体运行速度,反而会在用户再次激活这些进程时,加快进程的启动速度;因为不用重新加载界面资源了,这是Android标榜的特性之一;所以,Android现在不推荐显式的“退出”应用

优化内存空间

对象引用

从Java 1.2版本开始引入了三种对象引用方式:SoftReference、WeakReference 和 PhantomReference 三个引用类,引用类的主要功能就是能够引用但仍可以被垃圾回收器回收的对象。在引入引用类之前,只能使用Strong Reference,如果没有指定对象引用类型,默认是强引用。下面,我们就分别来介绍下这几种引用

强引用

如果一个对象具有强引用,GC就绝对不会回收它;当内存空间不足时,JVM会抛出OOM错误

软引用

如果一个对象只具有软引用,则内存空间足够,GC时就不会回收它;如果内存不足,就会回收这些对象的内存;可用来实现内存敏感的高速缓存

软引用可以和一个ReferenceQueue(引用队列)联合使用,如果软引用引用的对象被垃圾回收器回收,JVM会把这个软引用加入与之关联的引用队列中

弱引用

在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间是否足够,都会回收它的内存;不过,由于垃圾回收器是一个优先级很低的线程,因此不一定会很快发现那些只具有弱引用的对象

这里要注意,可能需要运行多次GC,才能找到并释放弱引用对象

虚引用

只能用于跟踪即将对被引用对象进行的收集。虚拟机必须与ReferenceQueue类联合使用。因为它能够充当通知机制

减少不必要的内存开销

AutoBoxing

自动装箱的核心就是把基础数据类型转换成对应的复杂类型。在自动装箱转化时,都会产生一个新的对象,这样就会产生更多的内存和性能开销;如int只占4字节,而Integer对象有16字节,特别是HashMap这类容器,进行增、删、改、查操作时,都会产生大量的自动装箱操作

检测方式

使用TraceView查看耗时,如果发现调用了大量的integer.value,就说明发生了AutoBoxing

内存复用

对于内存复用,有如下四种可行的方式:

  • 资源复用:通用的字符串、颜色定义、简单页面布局的复用
  • 视图复用:可以使用ViewHolder实现ConvertView复用
  • 对象池:显示创建对象池,实现复用逻辑,对相同的类型数据使用同一块内存空间
  • Bitmap对象的复用:使用inBitmap属性可以告知Bitmap解码器尝试使用已经存在的内存区域,新解码的bitmap会尝试使用之前那张bitmap在heap中占据的pixel data内存区域

内存问题

那么,内存问题主要是有哪几类呢?内存问题通常来说,可以细分为如下三类:

内存抖动

内存泄漏

内存溢出

内存抖动

内存波动图形呈锯齿张GC导致卡顿

这个问题在Dalvik虚拟机上会更加明显,而ART虚拟机内存管理跟回收策略上都做了大量优化内存分配和GC效率相比提升了5~10倍,所以出现内存抖动的概率会小很多

内存泄漏

Android系统虚拟机的垃圾回收是通过虚拟机GC机制来实现的。GC会选择一些还存活的对象作为内存遍历的根节点GC Roots,通过对GC Roots的可达性来判断是否需要回收。内存泄漏就是在当前应用周期内不再使用的对象被GC Roots引用,导致不能回收,使实际可使用内存变小;简言之,就是对象被持有导致无法释放或不能按照对象正常的生命周期进行释放;一般来说,可用内存减少、频繁GC,容易导致内存泄漏

内存溢出

即OOM,OOM时会导致程序异常。Android设备出厂以后,java虚拟机对单个应用的最大内存分配就确定下来了,超出这个值就会OOM。单个应用可用的最大内存对应于 /system/build.prop 文件中的 dalvik.vm.heapgrowthlimit

此外,除了因内存泄漏累积到一定程度导致OOM的情况以外,也有一次性申请很多内存,比如说一次创建大的数组或者是载入大的文件如图片的时候会导致OOM;而且,实际情况下很多OOM就是因图片处理不当而产生的

Android内存的意义

其实咱们在用安卓手机的时候不用太在乎剩余内存,Android上的应用是java,固然须要虚拟机,而android上的应用是带有独立虚拟机的,也就是每开一个应用就会打开一个独立的虚拟机

其实和java的垃圾回收机制相似,系统有一个规则来回收内存。进行内存调度有个阀值,只有低于这个值系统才会按一个列表来关闭用户不须要的东西。固然这个值默认设置得很小,因此你会看到内存老在不多的数值徘徊。但事实上他并不影响速度。相反加快了下次启动应用的速度

这原本就是 android标榜的优点之一,若是人为去关闭进程,没有太大必要。特别是使用自动关进程的软件;为何内存少的时候运行大型程序会慢呢?缘由是:在内存剩余很少时打开大型程序时会触发系统自身的调进程调度策略,这是十分消耗系统资源的操做,特别是在一个程序频繁向系统申请内存的时候

这种状况下系统并不会关闭全部打开的进程,而是选择性关闭,频繁的调度天然会拖慢系统

今天的分享到此就结束了,感谢您的阅读,如果确实帮到您,您可以动动手指转发给其他人。

发表回复