Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid keeping a strong reference to caches being monitored #2643

Merged

Conversation

slovdahl
Copy link
Contributor

@slovdahl slovdahl commented Jun 9, 2021

Fixes #2642.

@slovdahl
Copy link
Contributor Author

slovdahl commented Jun 9, 2021

I'm getting test failures locally in CaffeineCacheMetricsTest.reportExpectedGeneralMetrics, and I can't figure why that is. Works fine locally on upstream main.

Copy link
Member

@shakuzen shakuzen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementations of Gauge and FunctionCounter do not call the value function if the underlying obj is null. For example, in CacheMeterBinder, where it has

FunctionCounter.builder("cache.gets", cache.get(), c -> hitCount())

if the weak reference's get() returns null then the hitCount() method will not be called. This is why with the current implementation, we don't really care what the abstract methods return if the cache is GC'd because they won't be called. This behavior is not very apparent and took me a bit of looking at it to realize.

@slovdahl
Copy link
Contributor Author

slovdahl commented Jun 9, 2021

@shakuzen do you want me to fix all the caches in this same PR, or should I do it in separate PRs?

@slovdahl
Copy link
Contributor Author

slovdahl commented Jun 10, 2021

@shakuzen do you want me to add some tests for validating that no strong reference is kept? It's probably doable by doing one or more System.gc() calls after clearing the reference to the Cache instance.

@shakuzen
Copy link
Member

Yes, I think the cause and fix is the same for all so fixing them all in the same pull request sounds reasonable to me. And yes, a test would be good. I have one locally I can work into the pull request if you don't feel like making one.

@slovdahl
Copy link
Contributor Author

Yes, I think the cause and fix is the same for all so fixing them all in the same pull request sounds reasonable to me

I'll update the PR with the same kind of fix for all them then 👍

And yes, a test would be good. I have one locally I can work into the pull request if you don't feel like making one.

Sounds great!

@slovdahl
Copy link
Contributor Author

Updated the PR accordingly. AFAICT, the JCacheMetrics class does not need any WeakReference wrapping. Do you agree with that?

@slovdahl slovdahl changed the title Avoid keeping a strong reference to Caffeine caches being monitored Avoid keeping a strong reference to caches being monitored Jun 15, 2021
@jonatan-ivanov
Copy link
Member

jonatan-ivanov commented Jun 22, 2021

This looks good to me the only thing I miss is testing this, I guess we have two issues here:

  1. Forcing weak references to return null
  2. Preventing weak references to return null (if GC will clean things up during tests, our current tests could break since we will get the default value)

@shakuzen Could you please share what do you have locally to test this?
I'm thinking about having another ctor that accepts a reference so that we can control it and simulate "GC" events (I'm not sure mocking (mockito) a reference can work at all):

public class MockReference<T> extends WeakReference<T> {
    private T referent;

    public MockReference(T referent) {
        super(referent);
        this.referent = referent;
    }

    @Nullable
    @Override
    public T get() {
        return this.referent;
    }

    public void simulateGC() {
        this.referent = null;
    }
}

@shakuzen shakuzen self-assigned this Jun 23, 2021
@shakuzen
Copy link
Member

@shakuzen Could you please share what do you have locally to test this?

It may depend on the JVM and GC, but at least in my testing locally, it was reliable enough to do the following to garbage collect the cache:

cache = null;
System.gc();

@shakuzen shakuzen force-pushed the 2642-caffeine-weak-reference branch from f7de149 to 99bd536 Compare August 26, 2021 13:55
@shakuzen shakuzen changed the base branch from main to 1.6.x August 26, 2021 13:55
@shakuzen shakuzen force-pushed the 2642-caffeine-weak-reference branch from 99bd536 to a333965 Compare August 27, 2021 12:28
@shakuzen shakuzen changed the base branch from 1.6.x to main August 27, 2021 12:28
@shakuzen
Copy link
Member

I added some generics and the dereference test to the cache metrics TCK. The current build failure looks unrelated. We'll see if we can get that resolved.

@shakuzen shakuzen force-pushed the 2642-caffeine-weak-reference branch from a333965 to 47a8ca0 Compare August 30, 2021 08:07
@shakuzen shakuzen force-pushed the 2642-caffeine-weak-reference branch from 47a8ca0 to 07607dc Compare August 30, 2021 08:39
@shakuzen
Copy link
Member

I was going to merge this to the maintenance branches originally, but with the addition of generics, it is more appropriate to include this in the next feature release. We can separately consider a back-port to maintenance branches without the generics if there is demand.

@shakuzen shakuzen merged commit 8b95a6b into micrometer-metrics:main Aug 30, 2021
@slovdahl slovdahl deleted the 2642-caffeine-weak-reference branch August 31, 2021 05:01
izeye added a commit to izeye/micrometer that referenced this pull request Oct 20, 2021
izeye added a commit to izeye/micrometer that referenced this pull request Oct 20, 2021
shakuzen pushed a commit that referenced this pull request Oct 20, 2021
shakuzen pushed a commit that referenced this pull request Oct 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Monitored Cache is not eligible for garbage collection
3 participants