Android内存优化之内存缓存

前言:

上面两篇博客已经讲了图片的基本知识图片的加载方法及优化,所有的这些优化都是为了避免应用出现OOM这个问题。一个好的应用程序不仅要健壮不能出错还要方便用户使用,对于用户来说你的应用不仅要美观还要流畅,很快的呈现给他想要的。很快的加载图片除了加载的优化外还需要缓存,下面这篇博客将会讲图片缓存。

什么是缓存?

缓存技术原理就是把用户访问的所有对象看作一个全集,经过算法标记哪些是用户经常访问的对象,把这些对象放到一个集合里,这个集合是全集一个子集,下一次用户再访问的时候会先从这个子集集合中查找用户要访问的对象如果找到就直接返回这个对象,如果没有找到则再去全集中查找。当然了我这里说的只是原理性的东西,缓存是有很多算法的,并且有的不止一级缓存,这里就不过多讲了。

为什么要用到缓存?

有缓存的话可以不必每次从源地址读取文件,既节省了时间也节省了流量。尤其是手机设备,频繁的访问网络资源会消耗很多用户的流量和电量,这是用户不能忍受的,所以无论从哪个方面考虑应用程序都必须加上缓存。

Android中的图片缓存有哪些?各有什么特点?

Android设备的图片缓存分两种,一种是内存缓存,图片缓存在设备的内存中,一种是外部缓存,图片缓存在磁盘上,磁盘可以是内部的存储空间也可以是外部的sd卡。这两种缓存各有各的优点,内存缓存优点是快,缺点是因为也是读取到内存中所以也会消耗内存,所以不能太大,用的时候要考虑分配的空间,还有一个缺点是应用重启后就会消失。外部缓存的优点是可以长久保存大量的数据(相比较内存缓存而言),缺点就是慢。

内存缓存:

在Android中官网推荐使用LruCache作为内存缓存,LruCache实际上就是一个LinkedHashMap( 补充知识:LinkedHashMap是一个双向循环列表,不支持线程安全,LruCache对它进行了封装添加了线程安全操作),里面保存了一定数量的对象强引用,每次添加的新对象都是在链表的头,当分配的空间用完的时候会把末尾的对象移除,移除的对象就可以被gc回收了。这里需要注意一下LruCache的容量,这个容量既不能太大,会造成OOM,又不能太小,起不到缓存的作用。google官网给出一下意见作为参考:

  • 分配LruCache大小的时候考虑你的应用剩余内存有多大;
  • 一次屏幕显示多少张图片,有多少张图片是缓存起来准备显示的;
  • 考虑你的手机分辨率和尺寸, 缓存相同的图片个数,dpi越大的手机需要的内存就会越大,我的一篇博客中()有讲解;
  • 图片分辨率和像素质量也决定了占用内存的大小;
  • 图片访问的频繁程度是多少,是不是有一些图片是经常访问的?如果存在你可以考虑用多个LruCache来做缓存,按照访问的频率度分配到不同的LruCache中;
  • 如何平衡一下图片质量和数量,有些时候可以考虑缓存低分辨率的图片,用到的时候再在后台请求更高质量的图片;

总之你分配的LruCache大小既不能太大,又不能太小,具体到应用中还要你综合考虑。

下面的代码是使用LruCache的例子:

1

2

3

4

5

6

7

8

9

10

11

private LruCache<String, Bitmap> mMemoryCache;//声明缓存空间

final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);//获取应用在系统中的最大内存分配

//分配1/8的应用内存作为缓存空间

final int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {

@Override

protected int sizeOf(String key, Bitmap bitmap) {

//重写sizeOf方法,返回图片的占用字节数而不是图片的个数,每次添加图片是会被调用

return bitmap.getByteCount() / 1024;

}

};

注意:有同学可能会问下面的代码:

1

2

3

4

5

intcacheSize=4*1024*1024;// 4MiB

LruCachebitmapCache=newLruCache(cacheSize){

protectedintsizeOf(Stringkey,Bitmapvalue){

returnvalue.getByteCount();

}}

这两个sizeOf的计算是不一样的,这里说明一下,这个方法重写的目的是返回图片占用的缓存空间而不是图片的数目,并且这个数值的单位要和cacheSize一样。

总结:

综合上面的讲解,在使用内存缓存LruCache时你需要知道如下知识:

  • LruCache封装了LinkedHashMap,提供了LRU(Least Recently Used 最近最少使用算法)缓存的功能;
  • LruCache通过trimToSize方法自动删除最近最少访问的键值对;
  • LruCache不允许空键值, LinkedHashMap允许;
  • LruCache线程安全, LinkedHashMap线程不安全;
  • 继承LruCache时,必须要复写sizeOf方法,用于计算每个条目的大小。在put和get的时候会调用safeSizeOf(K key, V value),safeSizeOf(K key, V value)会调用 sizeOf (K key, V value),这个方法默认返回1。

关注微信公众平台:程序员互动联盟(coder_online),你可以第一时间获取原创技术文章,和(java/C/C++/Android/Windows/Linux)技术大牛做朋友,在线交流编程经验,获取编程基础知识,解决编程问题。程序员互动联盟,开发人员自己的家。

时间: 2024-10-09 08:41:33

Android内存优化之内存缓存的相关文章

[Android 性能优化系列]内存之终极篇--降低你的内存消耗

大家如果喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地址:http://developer.android.com/training/articles/memory.html 在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家 建议大家在看本文之前先去我的博客看看 [Android 性能优化系列]内存之基础篇--Andr

[Android 性能优化系列]内存之基础篇--Android怎样管理内存

大家假设喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地址:http://developer.android.com/training/articles/memory.html 在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家 以下是本次的正文: ################ 随机訪问存储器(Ram) 无论在哪种软件

Android 性能优化之内存泄漏检测以及内存优化(上)

在 Java 中,内存的分配是由程序完成的,而内存的释放则是由 Garbage Collecation(GC) 完成的,Java/Android 程序员不用像 C/C++ 程序员一样手动调用相关函数来管理内存的分配和释放,虽然方便了很多,但是这也就造成了内存泄漏的可能性,所以记录一下针对 Android 应用的内存泄漏的检测,处理和优化的相关内容,上篇主要会分析 Java/Android 的内存分配以及 GC 的详细分析,中篇会阐述 Android 内存泄漏的检测和内存泄漏的常见产生情景,下篇会

Android应用优化之内存概念

导语 现在的Android智能手机发展信息万变,从一开始的HTC到小米价格战到现在高端市场份额战,在软硬件都发生了翻天覆地的变化.在硬件上内存从一开始的一两百M到现在4G.从软件上我们从一开始为了实现需求而写代码到现在为了代码更健壮.更漂亮而进行不断优化代码.这些都是Android发展的必然一步.今天我来跟大家一起分享Android内存优化的相关概念和实践. 概念 进程内存与RAM之间的关系 进程内存既是虚拟内存(或者叫逻辑内存),而程序的运行需要实实在在的内存,即物理内存(RAM),在需要的时

Android 如何优化APP内存

极力推荐Android 开发大总结文章:欢迎收藏 程序员Android 力荐 ,Android 开发者需要的必备技能 随机存取存储器(RAM)在任何软件开发环境中都是非常有价值的资源,但对于物理内存经常受到限制的移动操作系统来说,它更有价值. 尽管Android运行时(ART)和Dalvik虚拟机都执行常规垃圾收集,但这并不意味着您可以忽略应用程序分配和释放内存的时间和位置. 您仍然需要避免引入内存泄漏,通常由静态成员变量中的对象引用引起,并在生命周期回调定义的适当时间释放任何引用对象. 本页面

[Android 性能优化系列]内存之基础篇--Android如何管理内存

大家如果喜欢我的博客,请关注一下我的微博,请点击这里(http://weibo.com/kifile),谢谢 转载请标明出处(http://blog.csdn.net/kifile),再次感谢 原文地址:http://developer.android.com/training/articles/memory.html 在接下来的一段时间里,我会每天翻译一部分关于性能提升的Android官方文档给大家 下面是本次的正文: ################ 随机访问存储器(Ram) 不管在哪种软件

Android性能优化之内存优化

1.内存溢出的原因 1.1.内存泄漏 内存泄漏和内存溢出的区别: 内存泄漏:程序中存在对无用对象的引用,导致GC无法回收.内存泄漏最终会导致oom. 内存溢出:程序在申请内存时,没有足够的内存空间供其使用,出现out of memory. 1.2.保存多个耗用内存过大的对象 应用的某些逻辑操作消耗掉大量内存(譬如加载一张不经过处理的超大超高清图片等)导致超过阈值. 2.内存优化 2.1.bitmap 1)对bitmap进行压缩 通过BitmapFactory.Options设置inSampleS

Android性能优化之内存篇

http://www.cnblogs.com/flyme2012/p/dd1b11a4ea151458d77411f5e99bc0dc.html 下面是内存篇章的学习笔记,部分内容与前面的性能优化典范有重合,欢迎大家一起学习交流! 1)Memory, GC, and Performance 众所周知,与C/C++需要通过手动编码来申请以及释放内存有所不同,Java拥有GC的机制.Android系统里面有一个Generational Heap Memory的 模型,系统会根据内存中不同的内存数据类

Android内存优化9 内存检测工具3 MAT比Menmery Monitor更强大

在Android性能优化第(一)篇---基本概念中讲了JAVA的四大引用,讲了一下GCRoot,第二篇Memory Monitor检测内存泄露仅仅说了Menmery Monitor的使用,这篇博客谈一下MAT来寻找内存泄露,相对来说,Memory Monitor没有MAT强大,但是在开始介绍MAT之前,上两篇没有说清楚的问题先说一下. GC回收对可回收对象的判定什么样的对象是可以被回收的?当然是GC发现通过任何referencechain(引用链)无法访问某个对象的时候,该对象即被回收.名词GC

python性能优化、内存优化、内存泄露;与其他语音比较效率如何?

1.内存泄露:http://www.cnblogs.com/xybaby/p/7491656.html 2.内存优化:http://www.cnblogs.com/xybaby/p/7488216.html 3.性能提升:http://www.cnblogs.com/xybaby/p/6510941.html 4.与其他语音相比效率如何:http://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=python3&lang2=gpp