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

Fix memory leak with named instantiator #8153

Merged
merged 2 commits into from Jan 3, 2019
Merged

Fix memory leak with named instantiator #8153

merged 2 commits into from Jan 3, 2019

Conversation

melix
Copy link
Contributor

@melix melix commented Jan 3, 2019

Context

See #8142

@melix melix added in:core DO NOT USE a:bug labels Jan 3, 2019
@melix melix added this to the 5.1.1 milestone Jan 3, 2019
@melix melix self-assigned this Jan 3, 2019
@melix melix requested a review from oehme January 3, 2019 15:19
This commit reworks the named object instantiator so that it doesn't
leak memory, by locating the cache on the `VisibleURLClassLoader`
instance whenever possible. Previously, it retained strong references
to classes, meaning that any class loaded via a script classloader
would be strongly referenced and would prevent the loader from being
collected. With this change, the cache is now located on the loader
itself.

If, for some reason, the loader is not a known classloader, we will
still use a global cache, but this shouldn't leak memory anymore
since in this case it's likely the affected classes come from Gradle
core itself.

Fixes #8142
@@ -33,6 +36,28 @@
}
}

private final EnumMap<UserData, Object> userData = new EnumMap<UserData, Object>(UserData.class);
Copy link
Contributor

@oehme oehme Jan 3, 2019

Choose a reason for hiding this comment

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

⭕️ I think an enummap + synchronized here is not any better than using a concurrent hash map. I'd go with the latter, so we don't need to keep an enum of keys here, giving us better separation of concerns.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The EnumMap has the main advantage of having descriptive keys and optimized lookup/size. Also a ConcurrentMap will not prevent the same value from being computed concurrently, which we want to avoid (or we could have race conditions and linkage errors).


private LoadingCache<Class<?>, LoadingCache<String, Object>> newValuesCache() {
return CacheBuilder.newBuilder()
.weakKeys()
Copy link
Contributor

Choose a reason for hiding this comment

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

❌ Weak keys aren't necessary here (and won't help either)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Indeed, leftover of previous implementation.

This is unnecessary at this point.
@melix melix merged commit 8dc4e30 into release Jan 3, 2019
@melix melix deleted the cc/dm/issue-8142 branch January 3, 2019 18:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants