Android经典面试题之Glide的缓存大揭秘

news2025/5/21 1:17:41

本文首发于公众号“AntDream”,欢迎微信搜索“AntDream”或扫描文章底部二维码关注,和我一起每天进步一点点

Glide缓存

关联类:Engine、LruResourceCache、LruCache、ActiveResources

ActiveResources:弱引用缓存池
@VisibleForTesting final Map<Key, ResourceWeakReference> activeEngineResources = new HashMap<>();
private final ReferenceQueue<EngineResource<?>> resourceReferenceQueue = new ReferenceQueue<>();
LruCache:LinkedHashMap缓存池
private final Map<T, Entry<Y>> cache = new LinkedHashMap<>(100, 0.75f, true);

入口:Engine.load方法

先从缓存中取

--> loadFromMemory

--> loadFromActiveResources(弱引用池) 

--> loadFromCache 
--> getEngineResourceFromCache(LRU缓存池,LinkedHashMap)  

LRU缓存池中取到EngineResource后,会从LRU缓存中删除,然后对它引用计数+1,放入弱引用池

缓存中没有找到,就需要创建任务执行

-->  waitForExistingOrStartNewJob  
--> 如果当前图片任务已经有EngineJob了,就直接加个Callback

---> 没有的话就创建EngineJobDecodeJob从本地加载或者是网络加载

EngineResource通过引用计数来判断是否需要释放资源,释放的资源会从弱引用池中删除,放入LRU缓存中

缓存大小设置

涉及的类:MemorySizeCalculator

  • 首先获取App可用内存大小,Glide的内存大小限制在0.4以下,如果是低内存的系统,则是在0.33
private static int getMaxSize(
	ActivityManager activityManager, float maxSizeMultiplier, float lowMemoryMaxSizeMultiplier) {
	final int memoryClassBytes = activityManager.getMemoryClass() * 1024 * 1024;
	final boolean isLowMemoryDevice = isLowMemoryDevice(activityManager);
	//lowMemoryMaxSizeMultiplier是0.33
	//maxSizeMultiplier是0.4
	return Math.round(
			memoryClassBytes * (isLowMemoryDevice ? lowMemoryMaxSizeMultiplier : maxSizeMultiplier));
}

@TargetApi(Build.VERSION_CODES.KITKAT)
@Synthetic
static boolean isLowMemoryDevice(ActivityManager activityManager) {
	if (Build.VERSION.SDK\_INT >= Build.VERSION\_CODES.KITKAT) {
		return activityManager.isLowRamDevice();
	} else {
		return true;
	}
}
  • 图片缓存大小,用几屏来表示,跟屏幕的分辨率有关
//一屏的图片大小 宽*高*4(ARG888图片的像素大小就是4字节)
int screenSize = widthPixels * heightPixels * BYTES_PER_ARGB_8888_PIXEL;

//BitmapPool最新的是API26以上是4,以下的是1
int targetBitmapPoolSize = Math.round(screenSize * builder.bitmapPoolScreens);

//memoryCache是2屏
int targetMemoryCacheSize = Math.round(screenSize * builder.memoryCacheScreens);
  • LRU缓存动态限制图片缓存大小
 //在低内存回调,或是put新的图片后,都会进行缓存大小检查,如果超过就移除不太用的
protected synchronized void trimToSize(long size) {
	Map.Entry<T, Entry<Y>> last;
	Iterator<Map.Entry<T, Entry<Y>>> cacheIterator;
	while (currentSize > size) {
		cacheIterator = cache.entrySet().iterator();
		last = cacheIterator.next();
		final Entry\<Y> toRemove = last.getValue();
		currentSize -= toRemove.size;
		final T key = last.getKey();
		cacheIterator.remove();
		onItemEvicted(key, toRemove.value);
	}
}
DiskLruCache中的读写锁

写的时候会加锁,这个锁是自定义的,并且有一个锁的池子

 private static class WriteLock {
   final Lock lock = new ReentrantLock();
   int interestedThreads;

   @Synthetic
   WriteLock() {}
}

每次写的时候会加锁,并且会对这个WriteLock的interestedThreads分别在开始写和结束时进行加减操作

writeLocker.acquire(safeKey);
....
writeLocker.release(safeKey);

writeLocker从锁池子里取,key的话是用请求的key做哈希得到

 //SafeKeyGenerator.class
 private String calculateHexStringDigest(Key key) {
     PoolableDigestContainer container = Preconditions.checkNotNull(digestPool.acquire());
     try {
       key.updateDiskCacheKey(container.messageDigest);
       // calling digest() will automatically reset()
       return Util.sha256BytesToHex(container.messageDigest.digest());
     } finally {
       digestPool.release(container);
     }
}

锁的缓存做了2级,一级是通过上面的key和锁放在一个HashMap中;

//DiskCacheWriteLocker.class

private final Map<String, WriteLock> locks = new HashMap<>();
private final WriteLockPool writeLockPool = new WriteLockPool();

另一级是定义在内部类WriteLockPool的ArrayDeque里面,默认大小是10

 private static class WriteLockPool {
    private static final int MAX_POOL_SIZE = 10;
    private final Queue<WriteLock> pool = new ArrayDeque<>();
    ...
}

取的时候先从HashMap中取,取不到再从WriteLockPool中取

void acquire(String safeKey) {
    WriteLock writeLock;
    synchronized (this) {
      writeLock = locks.get(safeKey);
      if (writeLock == null) {
        writeLock = writeLockPool.obtain();
        locks.put(safeKey, writeLock);
      }
      writeLock.interestedThreads++;
    }

    writeLock.lock.lock();
}

释放锁的时候,会把writeLock的interestedThreads进行减一操作,如果为0了就释放锁,放入WriteLockPool中

void release(String safeKey) {
    WriteLock writeLock;
    synchronized (this) {
      writeLock = Preconditions.checkNotNull(locks.get(safeKey));
      if (writeLock.interestedThreads < 1) {
        ...
      }

      writeLock.interestedThreads--;
      if (writeLock.interestedThreads == 0) {
        WriteLock removed = locks.remove(safeKey);
        ...
        writeLockPool.offer(removed);
      }
    }

    writeLock.lock.unlock();
}

欢迎关注我的公众号AntDream查看更多精彩文章!

AntDream

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1881642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

React-Native优质开源项目

React Native 是一个由 Facebook 开发的开源框架&#xff0c;允许开发者使用 JavaScript 和 React 来构建原生移动应用。它允许开发者编写一次代码&#xff0c;然后可以在 iOS 和 Android 平台上运行&#xff0c;而无需为每个平台单独编写代码。以下是 React Native 的一些关键…

现代信息检索笔记(二)——布尔检索

目录 信息检索概述 IR vs数据库: 结构化vs 非结构化数据 结构化数据 非结构化数据 半结构化数据 传统信息检索VS现代信息检索 布尔检索 倒排索引 一个例子 建立词项&#xff08;可以是字、词、短语、一句话&#xff09;-文档的关联矩阵。 关联向量 检索效果的评价 …

ESP32-C3(基本信息)

ESP32-C3 是一款低功耗、高集成度的 MCU 系统级芯片 (SoC)&#xff0c;它集成了 2.4 GHz Wi-Fi 和低功耗蓝牙 (Bluetooth LE) 无线通信功能&#xff0c;并拥有丰富的外设接口和先进的电源管理机制。 主要特性&#xff1a; 无线通信&#xff1a; 支持 2.4 GHz Wi-Fi (802.11b/…

JVM(13):虚拟机性能分析和故障解决工具之Visual VM

1 Visual VM作用 是到目前为止随JDK发布的功能最强大的运行监视和故障处理程序&#xff0c;并且可以遇见在未来一段时间内都是官方主力发展的虚拟机故障处理工具。官方在VisualVM的软件说明中写上了“All-in-One”的描述字样&#xff0c;预示着他除了运行监视、故障处理外&…

SpringBoot实现文章点赞功能

提示&#xff1a;今日是2024年的6月30日&#xff0c;未来的你看到这篇文章&#xff0c;希望你依旧快乐 文章目录 前言 首先在这里前缀部分我就不做要求了,比如说登录信息什么的 数据库表格 这里实现点赞功能&#xff0c;主要是围绕论坛项目完成的 user_info代表用户信息表 for…

动态系统开发方法(DSDM): 基于RAD的全面指导与管理

目录 前言1. 动态系统开发方法概述1.1 DSDM的起源与背景1.2 DSDM的核心理念 2. DSDM的关键原则2.1 用户主动参与2.2 频繁交付2.3 时间盒管理2.4 高效的合作 3. DSDM的主要阶段3.1 可行性研究阶段3.2 业务研究阶段3.3 原型开发阶段3.4 设计与构建阶段3.5 部署阶段3.6 维护与支持…

MicroBin好用的粘贴板工具

有时候你可能想从一台电脑上粘贴文本到另一台电脑上&#xff0c;或者是你想要分享一张图片或者是一些文件&#xff0c;某些设备上登陆qq和微信有不太方便&#xff0c;那么就可以使用MicroBin&#xff0c;它不但可以实现跨设备复制粘贴的功能&#xff0c;还支持文件上传等功能 …

基于改进滑模、经典滑模、最优滑模控制的永磁同步电机调速系统MATLAB仿真

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 模型简介 针对永磁同步电机调速系统的响应性能和抗干扰能力问题&#xff0c;本文做了四个仿真&#xff0c;分别为&#xff1a;永磁同步电机的PID控制调速系统、基于传统滑模控制的永磁同步电机的调速系统、最…

Windows 系统 Solr 8.11.3 安装详细教程(最新)

Windows 系统 Solr 8.11.3 安装详细教程 说明什么是Solr下载与解压如何启动启动命令&#xff1a;浏览器中打开dashboard其他命令查看关闭命令 说明 本次只是简单安装&#xff0c;为了在项目中使用&#xff0c;如果在公开服务器中安装需要更改开放端口&#xff0c;配置权限等。 …

echarts 图例有数值但是柱子不显示问题

如图所示在做echarts图表时发现柱状图有数值&#xff0c;但是柱子没展示&#xff0c;后来发现这个没展示的数值是最小值和左侧y轴的最小值保持持平了&#xff0c;所以没有展示出来。 将下图中设置y轴最小值为0就可以了 yAxis: [{type: value,name: 产出,min: 0max: dataMax,ax…

使用Visual Studio Code记笔记

因为学习需要&#xff0c;记笔记是很有必要的&#xff0c;平常发CSDN&#xff08;都让CSDN是很棒的哈&#xff09;&#xff0c;后来使用VS Code的时候发现了很多插件&#xff0c;觉得做笔记还是相对不错的&#xff0c;主要用到的还是Markdown 主要设计的插件包括&#xff1a; …

为用户转出并处理MODIS NDVI数据案例过程记述,希望对大家有用!

最近为用户转出和处理了一次MODIS NDVI数据&#xff0c;我将过程做了个总结供大家参考&#xff01;希望能帮助到一些下载和处理数据的朋友! 使用工具为三个&#xff1a;地图资源工具 和 GIS数据转换器-栅格&#xff0c;qgis。 1.选择【数据下载功能】&#xff0c;然后选择MO…

【C++】相机标定源码笔记- 立体视觉相机的校准和图像矫正类

类主要用于双目相机的标定和矫正。它包含了读取和保存相机模型、计算标定参数以及矫正图像的功能。通过这些功能&#xff0c;可以实现双目相机的标定和矫正&#xff0c;从而提高双目相机的精度和稳定性。 公有函数&#xff1a; 构造函数、带参构造函数、析构函数、读取双目相机…

java基于ssm+jsp 房屋租赁系统

1 管理员登录 管理员输入个人的用户名、密码登录系统&#xff0c;这时候系统的数据库就会在进行查找相关的信息&#xff0c;如果我们输入的用户名、密码不正确&#xff0c;数据库就会提示出错误的信息提示&#xff0c;同时会提示管理员重新输入自己的用户名、密码&#xff0c;…

Allegro如何画2D弧形线?

Allegro如何画2D弧形线? 在用Allegro进行PCB设计时,画弧形线的主要是在对PCB进行邮票孔拼板的时候。 具体操作方法如下: 1、选择菜单栏Add 选择3pt Arc(3pt 圆弧) Add的下拉菜单的各项功能作用如下图

influxdb时序数据库使用

influxdb时序数据库使用 influxdb时序数据库使用免费influxdb申请云无服务器Telegraf安装influxdb安装mac安装Redhat && Centos安装docker安装Kubernetes安装windows安装 influx 网页使用influx CLI 安装influx命令行界面influx配置项权限认证配置管理 API 令牌InfluxD…

http.cookiejar.LoadError: Cookies file must be Netscape formatted,not JSON.解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

解析桥式整流电路

下面这个桥式整流电路出场率很高&#xff0c;看着一定眼熟。 事实证明&#xff0c;强行灌输的东西总是难以下咽。记得读书那会&#xff0c;第一次看到这个电路时被吓到了&#xff0c;以至于直到这门课结束了也没搞清楚。 本文就来分析一下此电路中电流的走向&#xff0c;进而理…

1、什么是SSD?

概念 SSD&#xff08;Solid State Drive&#xff09;固态硬盘&#xff0c;是以闪存为介质的存储设备&#xff1b;这里突出的重点是闪存。 闪存&#xff0c;也就是常说的flash&#xff0c;分为NOR 和 NAND&#xff1b; NOR的地址线和数据线分开&#xff0c;所以NOR芯片可以像…

Mojo — 适用于所有人工智能开发人员的编程语言

Mojo语言是一个由人工智能公司Modular推出的全新编程语言&#xff0c;专为AI开发者设计。Mojo的语法与Python相似&#xff0c;但结合了Python的易用性和C语言的高性能&#xff0c;旨在解锁AI硬件的可编程性和AI模型的可扩展性。 Modular这个公司则是一个非常年轻的新生AI创业公…