Implementing Lambda with Capture support makes Metaspace fills LambdaForms$BMH class
vladimir.x.ivanov at oracle.com
Wed May 3 12:34:13 UTC 2017
Thanks for the report and for the test case, Wenlei.
What you observe is an unfortunate consequence of LambdaForm
customization. It was introduced to speedup invocations of non-constant
method handles (MH.invoke/invokeExact on a method handle which isn't a
constant during JIT compilation).
As an example from your use case, in order to optimize for the value of
bound argument, the JIT compiler has to "see" it during the compilation.
The only way to achieve it right now is by issuing "specialized"
bytecode for the particular method handle and that's exactly what
happens during LambdaForm customization.
The generated class should go away once the method handle it was
generated for becomes unreachable, but it seems you construct plenty of
method handles for every query.
As a workaround, you can turn it off by specifying:
But I agree with Remi that it's a sign of a deeper problem in how you
use method handles. MH.bindTo() always produces a new method handle and
doesn't look like a good fit for implementing lambda capturing.
Method handles are designed for fast invocation. Some non-trivial amount
of work happens during method handle instantiation, so it should be
avoided in hot code. From performance perspective, one-time usage of
method handles never pays off. You should try to cache and reuse them in
order to observe speedups.
In particular, reusing the same method handle chain for all rows and
passing the value (from the table) explicitly should lead to a better
On 5/2/17 10:29 PM, Wenlei Xie wrote:
> We are implementing Lambda function with capture support in a SQL
> Engine. We currently implement by compiling user-written Lambda
> Expression into a MethodHandle. And use bindTo to captured fields. Thus
> for each row we will have a Bound Method Handle.
> However, we found JVM will generate the byte code Bound Method Handle
> once it's invoked more than 128 times. This cause in some cases (when
> the table has large arrays), the Metaspace fills with generated
> LambdaForm$BMH class.
> Here is the simple code to reproduce the
> issue: https://github.com/wenleix/BMHTest . It looks we cannot increase
> java.lang.invoke.MethodHandle.CUSTOMIZE_THRESHOLD beyond 128. Any
> suggestions to implement Lambda with Capture Support on JVM?
> Thank you !!
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
More information about the mlvm-dev