After a few runs against a large, multi-project build (180ish projects), I noticed that the configuration phase bogs down and CPU utilisation started to increase. I connected YourKit and saw back to back major collections, so I took a heap dump:
I’m not familiar enough with Gradle to know if the problem is simply the ‘gradle’ field reference in org.gradle.api.internal.changedetection.state.DefaultTaskArtifactStateCacheAccess holding onto an object that would have otherwise been collected, but it looks that way from a quick glance.
Happy to provide the heap dump to a Gradle developer if needed.
Hey,
This is actually intentional, we want the daemon to keep hold of the task artifact cache. This speeds up the build because we don’t have to read from disk and deserialize all the up-to-date data. This speed improvement does incur increased memory consumption but we believe the that speed boost is worth it.
In your project, what’s the % of the memory that is taken by this data?
In general, we work on improving daemon’s memory utilization. One of the things that we will fix in short-mid future is cache classloaders in the daemon. This improves daemon speed a lot.
60%. I haven’t spent a great deal of time looking at the code, but I don’t see any other references to that class. You’ve got a comment on that class, and it seems to me that if you initialised this in the constructor and didn’t hold the reference on the field, that object would be garbage collected:
private PersistentCache getCache() {
//TODO SF just do it in the constructor
But as I say, haven’t spent long, and I don’t understand the lifecycle of DefaultGradle and the objects it keeps alive, so it might be that this reference doesn’t matter.