三级缓存之内存缓存

三级缓存

  • 内存缓存, 优先加载, 速度最快
  • 本地缓存, 次优先加载, 速度快
  • 网络缓存, 不优先加载, 速度慢,浪费流量

我们需要知道: Android默认给每个app只分配16M的内存 无论手机的内存多大,既然是默认,可能不同的手机,厂家给分配的也不同,
我们可以通过Runtime.getRuntime().maxMemory()来动态获取.

理解内存中的缓存先要知道java中的引用,Java中有四种引用
- **java中的引用
- 强引用 垃圾回收器不会回收, java默认引用都是强引用
- 软引用 SoftReference 在内存不够时,垃圾回收器会考虑回收
- 弱引用 WeakReference 在内存不够时,垃圾回收器会优先回收
- 虚引用 PhantomReference 在内存不够时,垃圾回收器最优先回收**

我们需要知道:安卓2.3+以后会提前回收软引用,即使内存够用.

现在我们写一个简单的内存缓存

public class MemoryCacheUtils {private static HashMap<String, Bitmap> mMemoryCache = new HashMap<String, Bitmap>();public static Bitmap getBitmap(String key) {return mMemoryCache.get(key);}public static void setBitmap(String key, Bitmap bitmap) {mMemoryCache.put(key, bitmap);}
}

现在我们知道Android默认给每个app只分配16M的内存,如果使用这个map一直进行内存缓存的话,
肯定会发生内存溢出,因为你一直没有释放这些资源.你可能会问我们不是有垃圾回收机制吗? 垃圾回收机制只会回收没有引用的对象,也不是及时回收的.
其实我们这些引用也是强引用,垃圾回收机制任何时候都不会回收这些对象的.

刚才说了安卓2.3+以后会提前回收软引用,即使内存够用.现在对强引用进行一次包装,把他包装成软引用,这样及时内存够用也会及时回收这些软引用的.

public class MemoryCacheUtils {private static HashMap<String, SoftReference<Bitmap>> mMemoryCache = new HashMap<String, SoftReference<Bitmap>>();public static Bitmap getBitmap(String key) {SoftReference<Bitmap> softReference = mMemoryCache.get(key);if (softReference != null) {//有时候 被回收掉会是空的,进行一次非空判断return softReference.get();}return null;}public static void setBitmap(String key, Bitmap bitmap) {SoftReference<Bitmap> softReference = new SoftReference<>(bitmap);mMemoryCache.put(key, softReference);}}
但是新的问题也出现了. **软引用是解决内存溢出非常好的一种手段**,但是我们的目的是进行内存缓存,这样进行包装以后垃圾回收机制会很快的把这些软引用给回收掉,这样内存溢出的问题是解决了但是我们缓存的问题还没有得到解决  在过去,我们经常会使用一种非常流行的内存缓存技术的实现,即软引用或弱引用 (SoftReference or WeakReference)。但是现在已经不再推荐使用这种方式了,因为从 Android 2.3 (API Level 9)开始,垃圾回收器会更倾向于回收持有软引用或弱引用的对象,这让软引用和弱引用变得不再可靠。另外,Android 3.0 (API Level 11)中,图片的数据会存储在本地的内存当中,因而无法用一种可预见的方式将其释放,这就有潜在的风险造成应用程序的内存溢出并崩溃。--  ------以上是摘自谷歌官方文档翻译

现在谷歌推荐使用LruCache

**least recentlly use 最少最近使用算法**会将内存控制在一定的大小内, 超出最大值时会自动回收, 这个最大值开发者自己定

现在我们使用一下,体验一下它的强大之处.

public class MemoryCacheUtils {static LruCache<String, Bitmap> cache = null;//可以当做Map来使用static {long maxMemory = Runtime.getRuntime().maxMemory();System.out.println("手机的最大内存 : " + maxMemory);cache = new LruCache<String, Bitmap>((int) (maxMemory / 8)) {//指定要占用的最大内存//需要重写 ,默认返回一个字节@Overrideprotected int sizeOf(String key, Bitmap value) {//返回当前储存照片所需的内存   照片所需内存只与显示所占的像素点有关系,与原图片的大小无关系//return value.getByteCount()  //返回这个即可 下面返回是为了版本的兼容return value.getRowBytes() * value.getHeight();//行像素点*高 = 照片所占内存}};//一般取最大内存的八分之一}public static Bitmap getBitmap(String key) {return cache.get(key);}public static void setBitmap(String key, Bitmap bitmap) {cache.put(key, bitmap);}}

内存缓存和LruCache相关推荐

  1. Android 图片缓存之内存缓存技术LruCache,软引用

    Android 图片缓存之内存缓存技术LruCache,软引用

  2. 图片缓存之内存缓存技术LruCache,软引用

    图片缓存之内存缓存技术LruCache,软引用 每当碰到一些大图片的时候,我们如果不对图片进行处理就会报OOM异常, 这个 问题曾经让我觉得很烦恼 ,后来终于得到了解决, 那么现在就让我和大家一起分享 ...

  3. 剖析Picasso中的内存缓存机制——LruCache

    众所周知,Picasso是一个优秀的Android图片加载库.本篇并不讨论picasso的使用,而是来谈一谈picasso的缓存机制. 我们知道,目前主流的图片解决方案大部分都是三级缓存,即内存缓存. ...

  4. 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 缓存策略 | LruCache 内存缓存 | LruCache 常用操作 | 工具类代码 )

    文章目录 一.Bitmap 内存缓存策略 二.LruCache 内存缓存 三.LruCache 常用操作 四.LruCache 工具类 五.源码及资源下载 官方参考 : Google 官方提供的 内存 ...

  5. Android UIL图片加载缓存源码分析-内存缓存

    本篇文章我们来分析一下著名图片加载库Android-Universal-Image-Loader的图片缓存源码. 源码环境 版本:V1.9.5 GitHub链接地址:https://github.co ...

  6. 内存缓存LruCache实现原理

    自己项目中一直都是用的开源的xUtils框架,包括 BitmapUtils.DbUtils.ViewUtils和HttpUtils四大模块,这四大模块都是项目中比较常用的.最近决定研究一下 xUtil ...

  7. 【Android 内存优化】Bitmap 内存缓存 ( Bitmap 内存复用 | 弱引用 | 引用队列 | 针对不同 Android 版本开发不同的 Bitmap 复用策略 | 工具类代码 )

    文章目录 一.Bitmap 复用池 二.弱引用 Bitmap 内存释放 三.从 Bitmap 复用池中获取对应可以被复用的 Bitmap 对象 1.Android 2.3.3(API 级别 10)及以 ...

  8. 简单聊聊Glide的内存缓存

    前言 glide的内存缓存有两级:LruCache.ActiveResources 其中LruCache老生常谈了,这里就不细说了. ActiveResources实际上内含一个HashMap,Map ...

  9. Android-Universal-Image-Loader学习笔记(3)--内存缓存

    前面的两篇博客写了文件缓存.如今说说Android-Universal-Image-Loader的内存缓存.该内存缓存涉及到的类如图所看到的 这些类的继承关系例如以下图所看到的: 如同文件缓存一样,内 ...

最新文章

  1. 用一个二维码做下载地址,自动区分是 ios 还是 android
  2. HTML5对音频的支持
  3. VTK:Picking之HighlightSelection
  4. Qt与FFmpeg联合开发指南(二)——解码(2):封装和界面设计
  5. Selenium webdriver中的xpath定位
  6. Golang:无惧makefile
  7. java mysql结果集_Java JDBC结果集的处理
  8. 「 博客迁移声明 」迫于想折腾个人博客
  9. TensorFlow实现深度学习算法的教程汇集:代码+笔记
  10. 数据结构之查找-顺序查找,折半查找,分块查找
  11. keras cnn注意力机制_2019 SSA-CNN(自注意力机制)目标检测算法论文阅读笔记
  12. 每日算法系列【LeetCode 354】俄罗斯套娃信封问题
  13. 极速PDF打开文件后工具栏不显示怎么办
  14. 百度云OCR图片文字识别实现
  15. 女工下班路上被3男子拖入黑巷 身中10多刀身亡
  16. 维特比算法(Viterbi algorithm) 的理解
  17. 键盘功能键F1~F2的基本功能
  18. 如何在Linux虚拟器里新建跟目录,虚拟机linux 6 增加根目录
  19. 2020年末知识大总结:Java程序员转Android开发必读经验一份,嵌入式开发入门教程
  20. ServerSQL数据库查锁、解锁

热门文章

  1. Android 监听wifi总结
  2. 2023年电工杯数学建模竞赛A题:电采暖负荷参与电力系统功率调节的技术经济分析具体建模过程以及代码结果
  3. php中的or die,php or die() 语句,exit()
  4. WPF快速入门2—布局WrapPanel,DockPanel,StackPanel,Canvas
  5. 关于ARM9中的协处理器CP15及MCR/MRC指令
  6. nginx实现路由转发
  7. sublime text 3搭建Python3的开发环境
  8. 敏涵控股集团董事长刘敏:让世界了解敏涵 让敏涵走向世界
  9. MySQL实现7种 SQL JOINS
  10. 安装纯净版win10系统