Volley 详解之学到的不仅仅是volley

Volley是谷歌提供的网络访问框架,具体优缺点如下。
volley优势:
1. volley 存在2类线程,缓存线程 和 网络访问线程,默认会开取 1个缓存线程、4个网络访问线程。
2. volley 通过 采用 diskCache(磁盘缓存) + 内存缓存(缓存header信息) + 网络访问数据加载(ByteArrayPool 存放了网络请求的数据,放在内存)。
3. volley 通过缓存header信息,用来对请求进行校验,以达到缓存是否存在的校验,并且采用LRU策略(LinkedHashMap)来存放header信息。
4. ByteArrayPool 是从网络中请求数据后存放的地方,并且ByteArrayPool默认会申请64个内存地址,为了避免频繁的内存分配申请,从而减少响应时间,如果申请的空间太大则才进行分配。
5. 以上4个特点支持了Volley小数据量高并发的操作。
volley劣势:
对于大数据量的请求则性能低下,造成这个问题的原因有2点。
第一、ByteArrayPool将从网络请求来的数据加载在内存可能带来平凡性的GC甚至OOM;
第二、volley缓存采用的是磁盘缓存即DiskBaseCache类,当加载缓存数据的时候则需要从磁盘中读取大量数据到内存,同样可能引起平凡性GC或者OOM。

Volley优化点
第一、对于高访问率和小数据量的访问进行内存缓存,即支持三级缓存(volley只支持磁盘缓存即二级缓存),减少IO操作,从而提高并发速度;
第二,大数据量的访问,则采用切片访问磁盘,避免OOM。

volley 框架设计详解:
这里写图片描述

2、详细分析 volley 源码,从而深入理解volley框架设计。

  1. Volley是通过Volley.newRequestQueue作为入口启动的,见下图详解:
    这里写图片描述
  2. newRequestQueue 详解:
    这里写图片描述
  3. RequestQueue 详解:
    这里写图片描述
  4. addRequest详解:
    这里写图片描述
  5. 缓存线程处理详解:
    这里写图片描述
    这里写图片描述
  6. 网络线程详解:
    这里写图片描述
    这里写图片描述

缓存中使用的key实际上是url,缓存路径是 根节点 + url路径解析,见下图:
这里写图片描述
这里写图片描述
7. volley的本地缓存,是分为2部分,第一部分是内存的缓存,缓存的只是header的信息,另外一部分是磁盘缓存,在DiskBaseCache中,缓存的真实数据,见下图详解。
这里写图片描述
这里写图片描述
8. 网络请求,详情如下:
这里写图片描述
这里写图片描述
9. 网络访问之后,从服务器返回了数据,怎么处理的呢?volley是提前创建了一个内存池ByteArrayPool,这个类会一次默认创建64个内存模块,当获取到服务器数据之后申请空间时,则首先会在ByteArrayPool创建的默认内存模块中取查找是否有符合的内存模块,如果有则直接返回,这样是为了避免频繁性的申请内存空间,提高响应速度,如果申请的空间过大,默认内存模块不符合,才会进行重新内存分配。
这里写图片描述
这里写图片描述
10. 居然volley的缓存本质是内存中只缓存了header信息,真实数据是缓存在磁盘,那么我们接下来看看缓存数据是怎么获取的,回到缓存线程中对缓存数据的获取,如下图详解:
这里写图片描述
这里写图片描述
这里写图片描述

3、根据volley源码详解 和 框架设计详解 分析volley的优势和不足。
google在对volley框架解释的时候,提到了volley适合高并发少量数据的场景,而不适合大数据量的场景。通过以上源码分析可知,volley不适合大数据量场景的原因有2方面,第一,因为volley从网络获取数据之后直接加载到的内存,即 ByteArrayPool,大数据量容易造成OOM,并且ByteArrayPool中预先申请的64个内存空间有限,如果大数据量那么ByteArrayPool预先申请的内存模块无用武之地,不仅浪费了这64个内存模块的空间,每次申请内存空间也耗时;第二,volley对于真实数据是采用的磁盘缓存,如果数据量过大,IO过程过于耗时。相反,小数据量的高并发进程,因为本地缓存的存在,加上ByteArrayPool预先支配了64个内存模块区域,省掉了申请分配内存的时间,因此可以加快速度。

从源码中可以发现volley的缺点有以下几方面,第一,因为采用的磁盘缓存,IO过程毕竟耗时,优化的话可以考虑小数据量的可以考虑缓存到内存,超过某个数据量则再考虑缓存到磁盘;同时考虑到高并发性,如果小数据量缓存到内存,并发性太高的话,可能带来内存加剧,内存紧张的时候可能会导致内存被回收,那么可以考虑缓存到内存的同时也缓存到磁盘,内存无数据的时候再从磁盘加载。第二,IO过程,都是采用的 io类,我猜volley没有采用并发性更高的nio原因可能是缓存线程只有一个,如果需要提高高并发性的IO处理,可以考虑采用nio非阻塞式的处理方式。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值