深入理解Android缓存机制(一)缓存简介

CPU

CPU分为运算器跟控制器,是计算机的主要设备之一,功能主要是解释计算机指令以及处理计算机软件中的数据。计算机的可编程性主要是指对中央处理器的编程。中央处理器、内部存储器和输入/输出设备是现代电脑的三大核心部件。

存储器

存储器的种类很多,按用途可以分为主存储器和辅助存储器,下面依次介绍一下。

主存储器

又称内存是CPU能直接寻址的存储空间,它的特点是存取速率快。内存一般采用半导体存储单元,包括随机存储器(Random Access Memory)、只读存储器(Read Only Memory)和高级缓存(Cache)。

  • RAM:随机存储器可以随机读写数据,但是电源关闭时存储的数据就会丢失;
  • ROM:只能读取,不能更改,即使机器断电,数据也不会丢失
  • Cache:它是介于CPU与内存之间,常用有一级缓存(L1)、二级缓存(L2)、三级缓存(L3)(一般存在于Intel系列)。它的读写速度比内存还快,当CPU在内存中读取或写入数据时,数据会被保存在高级缓冲存储器中,当下次访问该数据时,CPU直接读取高级缓冲存储器,而不是更慢的内存。
辅助存储器

辅助存储器又称外存储器,简称外存,对于电脑而言,通常说的是硬盘或者光盘等,对于手机一般指的是SD卡,不过现在很多厂商都已经整合在一起了

缓存类型

  • 内存缓存:这里的内存主要指的存储器缓存
  • 磁盘缓存:这里主要指的是外部存储器,电脑指的是硬盘,手机的话指的就是SD卡

缓存容量

就是缓存的大小,到达这个限度之后,那么就需要进行缓存清理了

缓存策略

不管是内存缓存还是磁盘缓存,缓存的容量都是有限制的,所以跟线程池满了之后的线程处理策略类似,缓存满了的时候,我们也需要有相应的处理策略,常见的策略有:

  • FIFO(first in first out):先进先出策略,类似队列。

  • LFU(less frequently used):最少使用策略,RecyclerView的缓存采用了此策略。

  • LRU(least recently used):最近最少使用策略,Picasso在进行内存缓存的时候采用了此策略。

当缓存容量达到设定的容量的时候,会根据制定的策略进行删除相应的元素。

内存泄露

这个主要发生在内存缓存中,当生命周期段的对象持有了生命周期长的对象的引用就会发生内存泄露,解决这种问题通常有两种方式

  • 引用置空:将缓存中引用的对象置空,然后GC就能够回收这些对象
  • 采用弱引用:采用弱引用关联对象,这样就能够不干涉对象的生命周期,以便GC能够正常回收

实际上在防止内存泄露的过程中这两种方式都使用地比较平凡,不过我们大多数时候使用的还是弱引用。

其实Java有四种引用,强引用,软引用,弱引用,虚引用,这些并没什么好说的,我们平时使用最多的还是弱引用,也就是WeakReference。

弱引用VS软引用

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

下面简单描述一下这两种防止内存泄露的方法的区别

引用置空

RecyclerView的内部类LayoutManager持有了RecyclerView的使用,没有采用弱引用,但是提供了置空的方法

public static abstract class LayoutManager {
ChildHelper mChildHelper;
RecyclerView mRecyclerView;
@Nullable
SmoothScroller mSmoothScroller;
private boolean mRequestedSimpleAnimations = false;
boolean mIsAttachedToWindow = false;
private boolean mAutoMeasure = false;
private boolean mMeasurementCacheEnabled = true;
private int mWidthMode, mHeightMode;
private int mWidth, mHeight;

void setRecyclerView(RecyclerView recyclerView) {
if (recyclerView == null) {
//回收
mRecyclerView = null;
mChildHelper = null;
mWidth = 0;
mHeight = 0;
} else {
//初始化
mRecyclerView = recyclerView;
mChildHelper = recyclerView.mChildHelper;
mWidth = recyclerView.getWidth();
mHeight = recyclerView.getHeight();
}
mWidthMode = MeasureSpec.EXACTLY;
mHeightMode = MeasureSpec.EXACTLY;
}

采用弱引用

用Picasso中的Action为例,父类采用了WeakReference

Action父类

abstract class Action {
final WeakReference target;
Action(Picasso picasso, T target, Request request, int memoryPolicy, int networkPolicy,
int errorResId, Drawable errorDrawable, String key, Object tag, boolean noFade) {
this.picasso = picasso;
this.request = request;
this.target =target ;
this.memoryPolicy = memoryPolicy;
this.networkPolicy = networkPolicy;
this.noFade = noFade;
this.errorResId = errorResId;
this.errorDrawable = errorDrawable;
this.key = key;
this.tag = (tag != null ? tag : this);
}

ImageAction子类

class ImageViewAction extends Action {
Callback callback;
ImageViewAction(Picasso picasso, ImageView imageView, Request data, int memoryPolicy,
int networkPolicy, int errorResId, Drawable errorDrawable, String key, Object tag,
Callback callback, boolean noFade) {
super(picasso, imageView, data, memoryPolicy, networkPolicy, errorResId, errorDrawable, key,tag, noFade);
this.callback = callback;
}

最后

在这里我和身边一些朋友特意整理了一份快速进阶为Android高级工程师的系统且全面的学习资料。涵盖了Android初级——Android高级架构师进阶必备的一些学习技能。

附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!
。)

[外链图片转存中…(img-cP0GHMjE-1715107073607)]

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

  • 14
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值