我是靠谱客的博主 刻苦身影,最近开发中收集的这篇文章主要介绍Caffeine - Caches - Eviction,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

Caffeine - Caches - Eviction

    • 剔除策略
      • 基于容量的剔除
      • 基于时间的剔除
      • 基于引用的剔除

剔除策略

Caffeine提供了三种类型的提出方式:基于容量的剔除、基于时间的剔除和基于引用的剔除。

基于容量的剔除

// Evict based on the number of entries in the cache
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .maximumSize(10_000)
    .build(key -> createExpensiveGraph(key));

// Evict based on the number of vertices in the cache
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .maximumWeight(10_000)
    .weigher((Key key, Graph graph) -> graph.vertices().size())
    .build(key -> createExpensiveGraph(key));

如果您的缓存不应超过特定大小,使用Caffeine.maximumSize(long)。 缓存将尝试剔除最近或很少使用的条目。

或者,如果不同的缓存条目具有不同的权重(例如,如果您的缓存值具有完全不同的内存占用量),你可以使用Caffeine.weigher(Weigher)指定权重函数,并使用Caffeine.maximumWeight(long)指定最大的缓存权重。除了与maximumSize相同的说明外,请注意,权重是在条目创建和更新时计算的,此后是静态的,并且在进行剔除选择时并不考虑权重因素。

基于时间的剔除

// Evict based on a fixed expiration policy
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .expireAfterAccess(5, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .expireAfterWrite(10, TimeUnit.MINUTES)
    .build(key -> createExpensiveGraph(key));

// Evict based on a varying expiration policy
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .expireAfter(new Expiry<Key, Graph>() {
      public long expireAfterCreate(Key key, Graph graph, long currentTime) {
        // Use wall clock time, rather than nanotime, if from an external resource
        long seconds = graph.creationDate().plusHours(5)
            .minus(System.currentTimeMillis(), MILLIS)
            .toEpochSecond();
        return TimeUnit.SECONDS.toNanos(seconds);
      }
      public long expireAfterUpdate(Key key, Graph graph, 
          long currentTime, long currentDuration) {
        return currentDuration;
      }
      public long expireAfterRead(Key key, Graph graph,
          long currentTime, long currentDuration) {
        return currentDuration;
      }
    })
    .build(key -> createExpensiveGraph(key));

Caffeine提供了三种方法进行基于时间的剔除。

  • expireAfterAccess(long, TimeUnit): 自条目最后一次读取或写入的时点开始、如果超过了方法指定的时长,标记条目过期。在缓存数据与session绑定并在不交互时过期的场景下使用比较理想。
  • expireAfterWrite(long, TimeUnit): 自条目创建或最后一次值替换的时点开始、如果超过了方法指定的时长,标记条目过期。如果经过一段时间后缓存数据过时,则可能需要这么做。
  • expireAfter(Expiry): 在可变持续时间过去之后标记条目过期。在条目的过期时间由外部资源决定的场景下使用比较理想。

过期处理是在写入期间和偶尔的读取期间进行的。到期事件的调度和触发的时间复杂度为 O(1)。

为了迅速到期,而不是依靠其他缓存活动来触发例行维护,请使用Scheduler接口和Caffeine.scheduler(Scheduler)方法在缓存构建器中指定一个调度线程。 Java 9+用户可能更喜欢使用Scheduler.systemScheduler()来利用专用的系统范围的调度线程。

测试过期剔除不需要在挂钟的时间消逝中等待。使用Ticker接口和Caffeine.ticker(Ticker)方法在缓存构建器中指定一个时间源,而不必等待系统时钟。为此,Guava的testlib提供了一个方便的实现FakeTicker。

基于引用的剔除

// Evict when neither the key nor value are strongly reachable
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .weakKeys()
    .weakValues()
    .build(key -> createExpensiveGraph(key));

// Evict when the garbage collector needs to free memory
LoadingCache<Key, Graph> graphs = Caffeine.newBuilder()
    .softValues()
    .build(key -> createExpensiveGraph(key));

Caffeine可以对keys或values使用弱引用,可以对values使用软引用,以此设置的缓存可以通过垃圾回收机制实现条目的回收。请注意,AsyncCache不支持弱引用和软引用。

Caffeine.weakKeys() 使用弱引用存储key。如果没有对key的强引用,缓存条目即可被垃圾回收掉。由于垃圾回收仅依赖identity equality,因此在进行key比较时只需要使用 == 即可,而不需要使用 equals()。

Caffeine.weakValues() 使用弱引用存储value。如果没有对value的强引用,缓存条目即可被垃圾回收掉。由于垃圾回收仅依赖identity equality,因此在进行value比较时只需要使用 == 即可,而不需要使用 equals()。

Caffeine.softValues() 使用软引用存储value。响应内存需求,软引用对象会以全局最近最少使用的方式进行垃圾回收。由于使用软引用会对性能产生影响,所以我们通常建议使用更可预测的设置最大缓存大小的方式来替代。使用softValues() 将导致value的比较是基于 == 而不是 equals()。

最后

以上就是刻苦身影为你收集整理的Caffeine - Caches - Eviction的全部内容,希望文章能够帮你解决Caffeine - Caches - Eviction所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部