前言

网络编程对于客户端来说是一块及其重要的地方,使用高效的网络请求框架将为你的系统产生很大的影响。而Volley作为谷歌的一个开源项目,炙手可热。有很多中小型公司的安卓移动客户端的网络程序都是基于volley的。 Volley的优点很多,光可扩展性这一条优点就值得我们称赞。但是我想针对的是在 Google I/O 2013 大会上发布Volley的时候的一句话:a burst or emission of many things or a large amount at once(爆炸性的事件在很短的时间内发生),意思就是:Volley特别适合数据量小,通信量大的客户端。同为网络请求框架,为什么Volley会有这样的特点?接下来,我就用我的理解来解释一下。

ByteArrayPool产生背景

根据类名,知道这是一个字节数组缓存池。没错,就是用来缓存 网络请求获得的数据。 当网络请求得到返回数据以后,我们需要在内存开辟出一块区域来存放我们得到的网络数据,不论是json还是图片,都会存在于内存的某一块区域,然后拿到UI显示,然而客户端请求是相当频繁的操作,想一下我们平时使用知乎等一些客户端,几乎每一个操作都要进行网络请求(虽然知乎大部分是WebView)。那么问题来了:这么频繁的数据请求,获得数据以后我们先要在堆内存开辟存储空间,然后显示,等到时机成熟,GC回收这块区域,如此往复,那么GC的负担就相当的重,然而Android客户端处理能力有限,频繁GC对客户端的性能有直接影响。我们能不能减少GC和内存的分配呢?我想这个问题就是这个类的产生背景。

实现原理(怎么实现缓存从而减少GC)

在ByteArrayPool中维护了两个List集合。

从缓冲区取空间

当请求数据返回以后,我们不是急于在内存开辟空间,而是从ByteArrayPool中取出一块已经分配的内存区域。此时会调用ByteArrayPool的getBuf(int)方法,来得到一块参数大小的区域,源码如下:

 public synchronized byte[] getBuf(int len) {
for (int i = ; i < mBuffersBySize.size(); i++) {
byte[] buf = mBuffersBySize.get(i);
if (buf.length >= len) {
mCurrentSize -= buf.length;
mBuffersBySize.remove(i);
mBuffersByLastUse.remove(buf);
return buf;
}
}
return new byte[len];
}

①方法的第2行代码,遍历mBuffersBySize,找到最适合len大小的byte[]。第6 ~8行更新缓存池中数据

②此方法主要的功能: 不必每次存数据都要进行内存分配,而是先查找缓冲池中有无适合的内存区域

③有的条件不需循环 if(len<=mSizeLimit)、

将空间返回给缓存池

如果只是拿数据,缓存区的只会越来越小,我们还需要向缓冲区中加入存储空间。这个时候涉及到一个方法
 public synchronized void returnBuf(byte[] buf) {
if (buf == null || buf.length > mSizeLimit) {
return;
}
mBuffersByLastUse.add(buf);
int pos = Collections.binarySearch(mBuffersBySize, buf, BUF_COMPARATOR);
if (pos < ) {
pos = -pos - ;
}
mBuffersBySize.add(pos, buf);
mCurrentSize += buf.length;
trim();
}
方法首先检查 要插入的数据大小有没有超出边界,如果没有,利用二分法找到插入位置,将数据插入到上述的两个集合,完成排序。然后更新缓冲池的大小,以方便从缓冲区中取存储空间。

结语

ByteArrayPool利用getBuf和returnBuf以及mBuffersByLastUse和mBuffersBySize完成字节数组的缓存。当需要使内存区域的时候,先从已经分配的区域中获得以减少内存分配次数。当空间用完以后,在将数据返回给此缓冲区。
这样,就会减少内存区域堆内存的波动和减少GC的回收,让CPU把更多的性能留给页面的渲染,提高性能。通过这个类发现,谷歌对技术的细节十分考究。


http://www.codekk.com/open-source-project-analysis/detail/Android/grumoon/Volley%20%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%90

Volley1--为什么说Volley适合数据量小,通信频繁的网络操作的更多相关文章

  1. PHP处理大数据量老用户头像更新的操作--解决数据量大超时的问题

    /** * @title 老用户头像更新--每3秒调用一次接口,每次更新10条数据 * @example user/createHeadPicForOldUser? * @method GET * @ ...

  2. elasticsearch5.0集群大数据量迁移方法及注意事项

    当es集群的数据量较小的情况下elasticdump这个工具比较方便,但是当数据量达到一定级别比如上百G的时候,elasticdump速度就很慢了,此时我们可以使用快照的方法进行备份 elasticd ...

  3. MySQL大数据量快速分页实现(转载)

    在mysql中如果是小数据量分页我们直接使用limit x,y即可,但是如果千万数据使用这样你无法正常使用分页功能了,那么大数据量要如何构造sql查询分页呢?     般刚开始学SQL语句的时候,会这 ...

  4. MySQL大数据量分页查询

    mysql大数据量使用limit分页,随着页码的增大,查询效率越低下. 测试实验 1.   直接用limit start, count分页语句, 也是我程序中用的方法: select * from p ...

  5. 【1】MySQL大数据量分页查询方法及其优化

    ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适应场景: 适用于数据量较少的情况(元组百/千 ...

  6. MySQL大数据量分页查询方法及其优化

    MySQL大数据量分页查询方法及其优化   ---方法1: 直接使用数据库提供的SQL语句---语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N---适 ...

  7. mysql--------大数据量分页sql语句优化

    分页程序原理很简单,这里就不多说了,本篇文章主要说的是在数据表记录量比较大的情况下,如何将分页SQL做到更优化,让MySQL执行的更快的方法. 一般的情况下,我们的分页SQL语句是这样的: ,; 以上 ...

  8. MySQL分页查询大数据量优化方法

    方法1: 直接使用数据库提供的SQL语句 语句样式: MySQL中,可用如下方法: SELECT * FROM 表名称 LIMIT M,N适应场景: 适用于数据量较少的情况(元组百/千级)原因/缺点: ...

  9. Mysql大数据量查询优化

    一般MYSQL最基本的分页方式: select * from content order by id desc limit 0, 10 在中小数据量的情况下,这样的SQL足够用了,唯一需要注意的问题就 ...

随机推荐

  1. Go语言类型转换

    类型转换用于将一种数据类型的变量转换为另外一种类型的变量. Go语言类型转换基本格式如下:表达式 T(v) 将值 v 转换为类型 T . Go语言各种类型转换及函数的高级用法:strconv包实现了基 ...

  2. 关于.NET中FileSystemWatcher的一些不被人注意的细节

    .NET 中的FileSystemWatcher可以监控文件系统中的更改.新建.删除和重命名,关于它的事件及属性的讨论有许多,但细节性的具体在什么情况下触发这些事件讨论不多.根据个人测试,总结如下: ...

  3. spring boot快速入门 9: 单元测试

    进行单元测试: service第一种方式: 第一步:在指定service中创建一个方法进行测试 /** * 通过ID查询一个女生的信息 * @param id * @return */ public ...

  4. web服务器/应用服务器

    1.概念 Web服务器的基本功能就是提供Web信息浏览服务.它只需支持HTTP协议.HTML文档格式及URL.与客户端的网络浏览器配合.因为Web服务器主要支持的协议就是HTTP,所以通常情况下HTT ...

  5. 132页Filter代码分析

    1.long before = System.currentTimeMillis(); long after = System.currrentTimeMillis(); 解析:这两段代码之间定义的是 ...

  6. golang的bytes.NewReader函数出现的问题

    在我试图装入一个300mb的数据时,发生了溢出. 我本以为不会出现这种问题的(内存和硬盘都够用),可见golang的bytes包还是设置了容量限制的. 虽然通常来说300mb的[]byte不管什么情况 ...

  7. Entity Framework 6.0 Code First(转)

    源自:http://www.cnblogs.com/panchunting/tag/Code%20First/ 1 Conventions 2 Custom Conventions 3 Data An ...

  8. 百度优先收录HTTPS网站?你的网站https还在等什么

    2015年5月25日,百度站长平台发布的公告,称将正式开放对HTTPS站点的收录.开始优先抓取HTTPS站点.所有事情都有两面性,这个消息对于已 经到HTTPS的网站来说是个喜大普奔的好消息.对于需要 ...

  9. Web前端学习资料

    http://www.imooc.com/course/list?c=html http://www.w3cplus.com/ http://www.w3cfuns.com/ http://www.w ...

  10. [转]C#进阶系列——WebApi 接口返回值不困惑:返回值类型详解

    本文转自:http://www.cnblogs.com/landeanfen/p/5501487.html 阅读目录 一.void无返回值 二.IHttpActionResult 1.Json(T c ...