作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
在并发环境下的map,第一想到的就是sync.Map,但是在读多写少的情况下,sync.Map的查询性能不如map;且,sync.Map的内存结构更加复杂,不便于准确的控制总内存量。
于是VM中应用了这样一些技巧来避免使用synv.Map:
- 对象中使用了两个map,分为mutable可变和immutale不可变;
- 查询的时候,先不加锁查询immutable,如果查询不到,再加锁查询mutable;
- 写入数据的时候,加锁写入mutable;
- 查询的时候触发mutable到immutable的迁移:
- 内部记录一个下次迁移时间,默认是10秒;也就是最短10秒才会触发mutable到immutable的搬迁;(业务场景允许)
- 搬迁的时候,把immutable写入到mutable,然后把当前的mutable作为immutable
- 为什么不是把mutable的数据写入immutable呢?因为immutable是读不加锁的,为了实现这部分查询的无锁,只能搬迁到新对象上去。
- 有时候,某个KEY的查询会非常频繁。因此会把最后一次命中的value写到额外的成员变量。查询的时候优先判断key是否是上次查询的key,如果是就直接返回缓存的value。这是某种意义的分支预测技术!