okhttp的字节缓存策略segment的问题

看okhttp源码看到segment时,根据methods的注释,有了以下理解,比如我segment的双向链表有3个实例:
Segment1[30]:表示实例1,字节数组内存占用百分30。

 * Segment1[30] <- Segment2[60]<- Segment3[10]
 *                  拆分Segment2
 * Segment1[30] <- Segment2[20]<- Segment2~[40]<- Segment3[10]
 *
 * 那么1,2可以compact,2,2~不能compact,2~,3不能compact吗?

我看源码在split Segment2的时候,将Segment2置为shared状态,然后将Segment2~置为owner=false的状态,意思是不可写。
在compact函数里,会判断 prev.shared && !prev.owner条件,满足这两个条件的相邻的Segment才可以compact成一个(这问题里容量判断的大前提默认都满足)。
那么按照它的意思,1,2可以compact,2,2~不能compact,2~,3不能compact吗?这么设计是为了避免什么问题?
小弟没理解其中意义。请各位指教。

阅读 2.1k
1 个回答

回去翻了一下okio的源码,Segment的shared和owner属性是互斥的,当对Segment2进行split时,如果Segment2被share了,会创建一个新的Segment共享原来的Segment2,这个Segment是处于shared状态且owner不是自己,链变成了
Segment1[30%]--->Segment2N(shared)[20%]--->Segment2(old)[40%]--->Segment3[10%]
其中Segment2N和Segment2(old)内部持有的byte[]数组对象是同一个,只是pos和limit位置不同,这就是shared状态,而Segment1和Segment3不是share状态,内部都是有各自的byte[]数组。

当遍历到Segment2N时,发现Segment2N和它的prev Segment1满足compact条件,就会compact Segment1和Segment2,把Segment2N里的数据写入Segment1里,然后把自身从链表中移除。
Segment1[50%]--->Segment2(old)[40%]--->Segment3[10%]

当遍历到Segment2(old)时,发现Segment2(40%)和Segment1(50%)都没有超过一半,满足compact条件,又会把Segment2(old)的数据写入Segment1里,把自身移除,释放内存。
Segment1[90%]--->Segment3[10%]

当遍历到Segment3时,不满足compat条件,没有必要拷贝数据,do nothing。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题