[ 
https://issues.apache.org/jira/browse/GROOVY-11152?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Oliver Gillespie updated GROOVY-11152:
--------------------------------------
    Description: 
I observed an issue in my application where it is continuously churning 
(loading, then later unloading) LambdaForm MethodHandle classes.

Note: some discussion on this in 
[https://lists.apache.org/thread/qmgsokwys9fkcozwq9vlmgnry14mdjwl].
{code:java}
[6.289s][info][class,init              ] 2754 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e64400' (0x0000000800e64400)
[6.289s][info][class,init              ] 2755 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e64800' (0x0000000800e64800)
[6.708s][info][class,nestmates         ] LookupDefineClass: 
java/lang/invoke/LambdaForm$MH - non-nestmate, hidden, weak, with vm annotations
[6.708s][info][class,nestmates         ] LookupDefineClass: 
java/lang/invoke/LambdaForm$MH - non-nestmate, hidden, weak, with vm annotations
[6.708s][info][class,load              ] 
java.lang.invoke.LambdaForm$MH/0x0000000800e64c00 source: 
__JVM_LookupDefineClass__
[6.708s][info][class,load              ] 
java.lang.invoke.LambdaForm$MH/0x0000000800e65000 source: 
__JVM_LookupDefineClass__
[6.708s][info][class,init              ] 2756 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e64c00' (0x0000000800e64c00)
[6.708s][info][class,init              ] 2757 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e65000' (0x0000000800e65000)
... etc.{code}
I have created a simple reproducer which demonstrates the issue.
{code:java}
// Run with
// JAVA_OPTS="-Xlog:class*=info" groovy test.groovy # java11 or java17
// JAVA_OPTS="-XX:+TraceClassLoading" groovy test.groovy # java8
// Observe a steady stream of LambdaForm classes being loaded, forever.

def foo(List<String> x) {  }
def bar(List<String> x) { foo(x) }

List<String> l1 = new ArrayList();
List<String> l2 = new LinkedList();

while (true) {
    bar(l1)
    127.times { bar(l2) }
}{code}
I'm using `Groovy Version: 4.0.13 JVM: 17.0.6-internal Vendor: Oracle 
Corporation OS: Linux`.

I originally noticed this because the class churning caused a memory leak (at 
least partially caused by [ 
[https://bugs.openjdk.org/browse/JDK-8313678]|https://bugs.openjdk.org/browse/JDK-8313678]),
but generally this much churn is bound to have negative performance 
implications. In my real application this is churning about 10 million classes 
per day.
I can avoid the issue when I spot it in my application by tweaking method 
arguments, but I'd be interested to know if this is a bug in Groovy and if it 
could
be fixed or there are any other more robust mitigations I can use.
I noticed https://issues.apache.org/jira/browse/GROOVY-8298 seems similar but 
not exactly the same, I think. The inline cache is not helping here, I'm not
sure if that's perhaps because the receiver is stable and it's the arguments 
which change?

I added logging to the sameClasses guard inserted in the invocation, and it's 
failing the guard because the argument types keep changing between LinkedList 
and ArrayList.

I believe this is a performance issue, as well as the high churn being likely 
to highlight bugs or issues in the JVM and things like attached profiling 
agents.

 

  was:
I observed an issue in my application where it is continuously churning 
(loading, then later unloading) LambdaForm MethodHandle classes.

Note: some discussion on this in 
https://lists.apache.org/thread/qmgsokwys9fkcozwq9vlmgnry14mdjwl.


{code:java}
[6.289s][info][class,init              ] 2754 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e64400' (0x0000000800e64400)
[6.289s][info][class,init              ] 2755 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e64800' (0x0000000800e64800)
[6.708s][info][class,nestmates         ] LookupDefineClass: 
java/lang/invoke/LambdaForm$MH - non-nestmate, hidden, weak, with vm annotations
[6.708s][info][class,nestmates         ] LookupDefineClass: 
java/lang/invoke/LambdaForm$MH - non-nestmate, hidden, weak, with vm annotations
[6.708s][info][class,load              ] 
java.lang.invoke.LambdaForm$MH/0x0000000800e64c00 source: 
__JVM_LookupDefineClass__
[6.708s][info][class,load              ] 
java.lang.invoke.LambdaForm$MH/0x0000000800e65000 source: 
__JVM_LookupDefineClass__
[6.708s][info][class,init              ] 2756 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e64c00' (0x0000000800e64c00)
[6.708s][info][class,init              ] 2757 Initializing 
'java/lang/invoke/LambdaForm$MH+0x0000000800e65000' (0x0000000800e65000)
... etc.{code}
I have created a simple reproducer which demonstrates the issue.
{code:java}
// Run with
// JAVA_OPTS="-Xlog:class*=info" groovy test.groovy # java11 or java17
// JAVA_OPTS="-XX:+TraceClassLoading" groovy test.groovy # java8
// Observe a steady stream of LambdaForm classes being loaded, forever.

def foo(List<String> x) {  }
def bar(List<String> x) { foo(x) }

List<String> l1 = new ArrayList();
List<String> l2 = new LinkedList();

while (true) {
    bar(l1)
    127.times { bar(l2) }
}{code}

I'm using `Groovy Version: 4.0.13 JVM: 17.0.6-internal Vendor: Oracle 
Corporation OS: Linux`.

I originally noticed this because the class churning caused a memory leak (at 
least partially caused by [ 
https://bugs.openjdk.org/browse/JDK-8313678|https://bugs.openjdk.org/browse/JDK-8313678]),
but generally this much churn is bound to have negative performance 
implications. In my real application this is churning about 10 million classes 
per day.
I can avoid the issue when I spot it in my application by tweaking method 
arguments, but I'd be interested to know if this is a bug in Groovy and if it 
could
be fixed or there are any other more robust mitigations I can use.
I noticed  https://issues.apache.org/jira/browse/GROOVY-8298 seems similar but 
not exactly the same, I think. The inline cache is not helping here, I'm not
sure if that's perhaps because the receiver is stable and it's the arguments 
which change?

I added logging to the sameClasses guard inserted in the invocation, and it's 
failing the guard because the argument types keep changing between LinkedList 
and ArrayList.

I believe this is a performance issue, as well as the high churn being likely 
to highlight bugs or issues in the JVM and thinks like attached profiling 
agents.




 


> Indy churning through LambdaForm classes
> ----------------------------------------
>
>                 Key: GROOVY-11152
>                 URL: https://issues.apache.org/jira/browse/GROOVY-11152
>             Project: Groovy
>          Issue Type: Improvement
>          Components: Compiler
>    Affects Versions: 4.0.13
>            Reporter: Oliver Gillespie
>            Priority: Minor
>
> I observed an issue in my application where it is continuously churning 
> (loading, then later unloading) LambdaForm MethodHandle classes.
> Note: some discussion on this in 
> [https://lists.apache.org/thread/qmgsokwys9fkcozwq9vlmgnry14mdjwl].
> {code:java}
> [6.289s][info][class,init              ] 2754 Initializing 
> 'java/lang/invoke/LambdaForm$MH+0x0000000800e64400' (0x0000000800e64400)
> [6.289s][info][class,init              ] 2755 Initializing 
> 'java/lang/invoke/LambdaForm$MH+0x0000000800e64800' (0x0000000800e64800)
> [6.708s][info][class,nestmates         ] LookupDefineClass: 
> java/lang/invoke/LambdaForm$MH - non-nestmate, hidden, weak, with vm 
> annotations
> [6.708s][info][class,nestmates         ] LookupDefineClass: 
> java/lang/invoke/LambdaForm$MH - non-nestmate, hidden, weak, with vm 
> annotations
> [6.708s][info][class,load              ] 
> java.lang.invoke.LambdaForm$MH/0x0000000800e64c00 source: 
> __JVM_LookupDefineClass__
> [6.708s][info][class,load              ] 
> java.lang.invoke.LambdaForm$MH/0x0000000800e65000 source: 
> __JVM_LookupDefineClass__
> [6.708s][info][class,init              ] 2756 Initializing 
> 'java/lang/invoke/LambdaForm$MH+0x0000000800e64c00' (0x0000000800e64c00)
> [6.708s][info][class,init              ] 2757 Initializing 
> 'java/lang/invoke/LambdaForm$MH+0x0000000800e65000' (0x0000000800e65000)
> ... etc.{code}
> I have created a simple reproducer which demonstrates the issue.
> {code:java}
> // Run with
> // JAVA_OPTS="-Xlog:class*=info" groovy test.groovy # java11 or java17
> // JAVA_OPTS="-XX:+TraceClassLoading" groovy test.groovy # java8
> // Observe a steady stream of LambdaForm classes being loaded, forever.
> def foo(List<String> x) {  }
> def bar(List<String> x) { foo(x) }
> List<String> l1 = new ArrayList();
> List<String> l2 = new LinkedList();
> while (true) {
>     bar(l1)
>     127.times { bar(l2) }
> }{code}
> I'm using `Groovy Version: 4.0.13 JVM: 17.0.6-internal Vendor: Oracle 
> Corporation OS: Linux`.
> I originally noticed this because the class churning caused a memory leak (at 
> least partially caused by [ 
> [https://bugs.openjdk.org/browse/JDK-8313678]|https://bugs.openjdk.org/browse/JDK-8313678]),
> but generally this much churn is bound to have negative performance 
> implications. In my real application this is churning about 10 million 
> classes per day.
> I can avoid the issue when I spot it in my application by tweaking method 
> arguments, but I'd be interested to know if this is a bug in Groovy and if it 
> could
> be fixed or there are any other more robust mitigations I can use.
> I noticed https://issues.apache.org/jira/browse/GROOVY-8298 seems similar but 
> not exactly the same, I think. The inline cache is not helping here, I'm not
> sure if that's perhaps because the receiver is stable and it's the arguments 
> which change?
> I added logging to the sameClasses guard inserted in the invocation, and it's 
> failing the guard because the argument types keep changing between LinkedList 
> and ArrayList.
> I believe this is a performance issue, as well as the high churn being likely 
> to highlight bugs or issues in the JVM and things like attached profiling 
> agents.
>  



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to