[
https://issues.apache.org/jira/browse/GROOVY-8092?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15886059#comment-15886059
]
Jesse Glick commented on GROOVY-8092:
-------------------------------------
bq. You mean no, they do not help if you use them
I do not recall trying those particular flags but anyway I cannot see what they
have to do with {{SoftReference}} collection.
bq. maybe it would be best to provide an official API for this
Well better still be to not hold on to any (non-weak) references to a
{{GroovyClassLoader}} from {{static}} fields in Groovy to begin with!
bq. if you say that is because the class has not been marked as softly reachable
Sorry, I am not following your argument at all. Currently {{GroovyClassLoader}}
instances are softly reachable, with a root reference chain starting in Groovy
code; and the Java 8 VM with default settings will not collect it (even after
{{System.gc()}}) until you force it to throw an {{OutOfMemoryError}} by
allocating giant arrays. If you use reflection to null out all the soft
references (leaving it only weakly reachable) then it is collected on the next
GC cycle. This is easily and consistently reproducible in an automated test,
and consistent with the very loose constraints defined in Javadoc.
bq. replacing the SoftReference with a hard one will actually increase the
problem
I think [~jwagenleitner]’s proposal was to use a strong reference only when the
class being inspected is already visible to Groovy’s own loader—for example,
something in Java Platform—and otherwise use a weak reference. This would
certainly solve the leak, at the expense of recalculating {{ClassInfo}}
metadata too often under memory pressure.
As noted in [JDK-6389107|https://bugs.openjdk.java.net/browse/JDK-6389107]
(filed by me years ago in a different context), without better Java Platform
support there is no perfect solution _in general_. In _this case_ we can
actually do better, because most of the problematic classes will in fact be
loaded by a {{GroovyClassLoader}}, which is code controlled by Groovy itself.
Thus the best algorithm would be to keep a metadata cache as an _instance_
field in {{GroovyClassLoader}} (probably irrelevant that {{InnerLoader}} is
actually the defining loader, since that is a {{GroovyClassLoader}} too), and:
* determine the defining loader of the class being inspected
* if an ancestor of the loader of Groovy itself, use a strong reference
* if a {{GroovyClassLoader}}, use a strong reference but keep the initial
lookup map in the newly introduced field
* otherwise use a weak reference
This will prevent any leaks, while ensuring that metadata is not recalculated
except in the relatively unusual case of classes defined in some unrelated
loader, at the expense of making the code which accesses the cache a little
more complex.
> Compatibility issues between groovy 2.4.8 and jenkins workflow-cps-plugin
> 2.23
> -------------------------------------------------------------------------------
>
> Key: GROOVY-8092
> URL: https://issues.apache.org/jira/browse/GROOVY-8092
> Project: Groovy
> Issue Type: Bug
> Components: groovy-runtime
> Affects Versions: 2.4.8
> Environment: Jenkins 2.19-stable with a single commit that bumps
> groovy 2.4.8
> workflow-cps-plugin 2.23
> Reporter: Ion Alberdi
>
> Created the issue on jenkins first
> https://issues.jenkins-ci.org/browse/JENKINS-42189
> Creating it here, in case the fix may be developed in groovy itself.
--
This message was sent by Atlassian JIRA
(v6.3.15#6346)