title: Caffeine cache - maximumSize eviction seems not to be late
body: <p>We have an issue with Caffeine cache. We configured it to be of size 60, with TTL of 300 seconds like this:</p>
  
  <pre><code>Cache&lt;String, String&gt; cache = Caffeine.newBuilder()
                  .expireAfterWrite(300, TimeUnit.SECONDS)
                  .maximumSize(60)
                  .removalListener((String key, String value, RemovalCause cause) -&gt; {
                      cacheListenerHandler(key, value, cause);
                  })
                  .build();
  </code></pre>
  
  <p>Now, the removalListener is defined like this:</p>
  
  <pre><code>private void cacheListenerHandler(String key, String value, RemovalCause cause) {
          if (RemovalCause.EXPIRED.equals(cause)) {
              if (value != null) {
                  LOG.info("We got TTL expiry of key {} and value {}",
                          key, value);
              } else {
                  LOG.warn("Value is null for TTL expiry! key: {}", key);
              }
          }
  
          if (RemovalCause.SIZE.equals(cause)) {
              if (value != null) {
                  LOG.info("We got SIZE expiry of key {} and value {}",
                          key, value);
                  //some logic
              } else {
                  LOG.warn("Value is null for SIZE expiry! key: {}", key);
              }
          }
      }
  </code></pre>
  
  <p>With that being said, we insert to the cache this way:</p>
  
  <pre><code>public void registerValue(String key, String value) {
          cache.put(key, value);
          LOG.info("Key {} was added with value {}. Current estimated size of {} keys in cache",
                  key, value, cache.estimatedSize());
  }
  </code></pre>
  
  <p>The issue is that sometimes we get logs such as:</p>
  
  <blockquote>
    <p>Key 'key1' was added with value 'value1'. Current estimated size of 250 keys in cache</p>
  </blockquote>
  
  <p>And we see constantly the eviction logs (of the listener method):</p>
  
  <blockquote>
    <p>We got SIZE expiry of key 'key1' and value 'value1'</p>
  </blockquote>
  
  <p>And a second later the log:</p>
  
  <blockquote>
    <p>Key 'key2' was added with value 'value2'. Current estimated size of 251 keys in cache</p>
  </blockquote>
  
  <p>Now, I know about the 'estimatedSize' nuance - it includes the keys that are going to be evicted, but the issue is that we get Java memory heap issues, meaning the actual removal happens too late for use.</p>
  
  <p>Is there a solution for it? Maybe we need to switch to Guava instead?</p>