Following an OOM (of Java heap) on a small (-Xmx512m) Jenkins instance, I've found in the heap dump ~ 760 000 jenkins.branch.MultiBranchProject$BranchIndexing objects (retaining 370 MB according to Eclipse MAT).
I was first suspecting that branch-scanning was somehow blocked and that these objects were piling up in the queue, but no, it is actually some past successful executions which are never garbage collected.
The explanation is simple, and it's not in the branch-api-plugin (although it would be possible to work-around the issue there), but in the cloudbees-folder-plugin.
See there:
- https://github.com/jenkinsci/branch-api-plugin/blob/branch-api-2.5.8/src/main/java/jenkins/branch/MultiBranchProject.java#L977
- https://github.com/jenkinsci/cloudbees-folder-plugin/blob/cloudbees-folder-6.14/src/main/java/com/cloudbees/hudson/plugins/folder/computed/FolderComputation.java#L135
- https://github.com/jenkinsci/cloudbees-folder-plugin/blob/cloudbees-folder-6.14/src/main/java/com/cloudbees/hudson/plugins/folder/computed/FolderComputation.java#L112
So, FolderComputations can optionally be chained (a computation can have a reference to the previous computation), via a private transient property. And BranchIndexing, indeed, sets this property.
What is this property for? It is only used to enable finding the previous Result, which is used for choosing an the icon color:
- FolderComputation#getPreviousResult(): https://github.com/jenkinsci/cloudbees-folder-plugin/blob/cloudbees-folder-6.14/src/main/java/com/cloudbees/hudson/plugins/folder/computed/FolderComputation.java#L450
- FolderComputation#getIconColor(): https://github.com/jenkinsci/cloudbees-folder-plugin/blob/cloudbees-folder-6.14/src/main/java/com/cloudbees/hudson/plugins/folder/computed/FolderComputation.java#L455
There is no accessor for this "previous" property other than this getPreviousResult() method, plus it's transient, so it is easily possible to avoid the infinitely growing linked list, and simply store the previous Result instead, without changing any public API.
I will submit a PR.