面试的时候你会遇到很多的问题,这些问题可能会把你难住,这恰恰是你平常没有注意到的细节或者知识点,回来后就可以针对这些方面进行学习提高。

在一次面试的时候,面试官问我关于 OOM 的问题,这很常见,也没有难住我,在我阐述了我的观点后,面试官又开始对这一方面进行深入的提问(面试官往往会从一点基础常见的问题开始,慢慢深入,来了解你的水平)。接下来他又问了我 OOM 中常见的 Bitmap 处理,这个比刚刚的问题深入了些,但是也在正常范围内,我又回答了他,主要是 Bitmap 转换的流的处理。之后他又对我回答的流的recycle() 方法进行提问,问我 recycle() 方法他的运行机制,这个就涉及到源码方面了。这个直接把我问住了,平常的开发中一般都是到 调用 recycle() 为止,还真没有点进去看下 recycle() 的机制。回来后赶紧点进去看了看,原来是这么回事。

/*** Free the native object associated with this bitmap, and clear the* reference to the pixel data. This will not free the pixel data synchronously;* it simply allows it to be garbage collected if there are no other references.* The bitmap is marked as "dead", meaning it will throw an exception if* getPixels() or setPixels() is called, and will draw nothing. This operation* cannot be reversed, so it should only be called if you are sure there are no* further uses for the bitmap. This is an advanced call, and normally need* not be called, since the normal GC process will free up this memory when* there are no more references to this bitmap.* *  释放被bitmap关联的本地内存,并且清除像素数据的引用。这个过程不会同步释放像素数据;*  它只是提醒 garbage 如果没有其他引用,那么它将会被其回收*  这张 bitmap 将会被标记 “dead” ,意味着当它在被调用 getPixels() 或setPixels()时会抛出异常。*  这个操作不能被撤销,所以只有当确认这个 bitmap 不会被再次引用的时候按此可以执行此操作*  这时一个高级方法,通常不需要主动调用它,因为当这个bitmap不会再次被引用时, GC会主动回收掉它并释放其内存*/
public void recycle() {if (!mRecycled && mFinalizer.mNativeBitmap != 0) {if (nativeRecycle(mFinalizer.mNativeBitmap)) {// return value indicates whether native pixel object was actually recycled.// false indicates that it is still in use at the native level and these // objects should not be collected now. They will be collected later when the// Bitmap itself is collected.//返回值表示是否本地像素对象是否被回收// false 表明它在本地仍在使用// 那些对象不会被立刻回收。他们将在被应用完之后被回收mBuffer = null;mNinePatchChunk = null;}mRecycled = true;}
}

这就是recycle() ,代码不多,就几行,我们一行行的来看下。
首先是第一重判断,这句判断主要是判别两个条件:
1. mRecycled 全局搜索下可以知道这是是否回收的标记值:

/*** Returns true if this bitmap has been recycled. If so, then it is an error* to try to access its pixels, and the bitmap will not draw.** @return true if the bitmap has been recycled*  如果 bitmap 已经被回收过将会返回 true*/
public final boolean isRecycled() {
    return mRecycled;
}

当调用多 recycle() 后这个标记值就会被置为 true,防止对一个对象进行多次recycle().

2.mFinalizer.mNativeBitmap 是否为0,这个参数点进去看下,我猜测他是bitmap的原始内存存储数组。

接下来是第二重判断:
nativeRecycle(),这是一个native 方法,同样作用是判断是否被回收了(关于这个 native 类型的方法具体要看Java,我也不是太懂)

private static native boolean nativeRecycle(long nativeBitmap);

如果两重判断都显示未进行回收过,那么久开始执行回收,将 mBuffer 置为空,mBuffer的注释是 Backing buffer for the Bitmap ,即是它的缓存,

/*** Backing buffer for the Bitmap.*/
private byte[] mBuffer;

并且将mNinePatchChunk 置为空,这个参数我没有找到它的注释,但是从它的字面意思上来看,它应该是 .9 的格式缓存数组,当然他也有一句注释,it may be null :

private byte[] mNinePatchChunk; // may be null

也就是说它有可能是为空的,看来并不是所有情况下都会给他赋值,当然为了保险起见还是将其置为空。
最后,将recycle() 的标记值置为true,意为已经进行过回收了。以上就是recycle() 的运行机制。

Bitmap recycle() 源码解析相关推荐

  1. Volley 源码解析之图片请求

    一.前言 上篇文章我们分析了网络请求,这篇文章分析对图片的处理操作,如果没看上一篇,可以先看上一篇文章Volley 源码解析之网络请求.Volley 不仅仅对请求网络数据作了良好的封装,还封装了对图片 ...

  2. Android之图片加载框架Picasso源码解析

    转载请标明出处: http://blog.csdn.net/hai_qing_xu_kong/article/details/76645535 本文出自:[顾林海的博客] 个人开发的微信小程序,目前功 ...

  3. Android Glide图片加载框架(二)源码解析之into()

    文章目录 一.前言 二.源码解析 1.into(ImageView) 2.GlideContext.buildImageViewTarget() 3.RequestBuilder.into(Targe ...

  4. Netty源码解析之内存管理-PooledByteBufAllocator-PoolArena

      PooledByteBufAllocator是Netty中比较复杂的一种ByteBufAllocator , 因为他涉及到对内存的缓存,分配和释放策略,PooledByteBufAllocator ...

  5. ImageLoader源码解析(一)

    ImageLoader源码解析(一) 本文章只解析初始化和加载一个图片的整体流程, 对于缓存的实现,线程的调度,涉及到的一些技术(线程池等) 放到以后再解析 1 文件目录解析 cache 缓存 cac ...

  6. Glide 4.9源码解析-图片加载流程

    本文Glide源码基于4.9,版本下载地址如下:Glide 4.9 前言 由于Glide源码真的很复杂,因此本文只分析和贴出与图片加载流程相关的功能以及代码.另外本文Glide源码基于4.9,与3.x ...

  7. Glide的源码解析(一)(附方法调用图)

    前言 上一篇博客讲了Glide的基本使用,知其然,也要知其所以然,这篇博客一起来学习Glide的源码.如果不知道Glide的基本使用,可以看上一篇博客:http://blog.csdn.net/luo ...

  8. [Android] Handler源码解析 (Java层)

    之前写过一篇文章,概述了Android应用程序消息处理机制.本文在此文基础上,在源码级别上展开进行概述 简单用例 Handler的使用方法如下所示: Handler myHandler = new H ...

  9. Heritrix 3.1.0 源码解析(八)

    本文接着分析存储CrawlURI curi的队列容器,最重要的是BdbWorkQueue类及BdbMultipleWorkQueues类 BdbWorkQueue类继承自抽象类WorkQueue,抽象 ...

最新文章

  1. c语言程序设计开卷考试b卷,C语言程序设计(B)试卷_杨崇联(A1).doc
  2. 强势回归!比 Python 快 20% 的 Pyston v2.0 来了!
  3. java response.write_@ResponseBody与response.getWriter .write()区别
  4. 关于端到端通信的讨论(P2P)
  5. ajax 传输中文乱码,关于Ajax请求中传输中文乱码问题的解决方案
  6. nginx 499 502 413 404 处理
  7. wepy小程序分包的版本
  8. UEditor的使用方法
  9. 六句话,看完新造车的2021
  10. 大学计算机基础通俗易懂教材,大学计算机基础(21世纪高等学校计算机规划教材)...
  11. 微信小程序商城API文档
  12. 关于指针的面试题,指向字符串和字符数组的单指针,二级指针,三级指针的使用。
  13. 长截图或长图片如何按页面切分后打印或插入到Word文档中
  14. html 隐藏表格某一行,layui怎么隐藏表格行?
  15. navicat 表合并查询_数据库两个表合并命令
  16. 各种LED显示模组的技术分析(1)扫描接口
  17. 对中间层的一些浅略的思考
  18. 手机号码归属地服务[转载]
  19. keepalived外界无法通过虚拟ip访问
  20. labview加python_python加labview教程

热门文章

  1. 三丰三坐标编程基本步骤_零基础学习工业机器人PLC编程的基本步骤
  2. linux脚本程序是什么意思,Linux中$?是什么意思?
  3. ​stp文件转iges
  4. 磁带库和磁带机的区别
  5. 人类小脑的功能连接组学
  6. 2020国赛C思路分析:中小微企业的信贷决策
  7. DotNetFX40
  8. 电子拍卖系统开发第二天
  9. 天气选择页面html,CSS3 天气预报界面组件
  10. 《神经网络与深度学习》-注意力机制与外部记忆