SpelCompiler / SpelExpression can leak classes when a compiled expression reverts back to interpreted mode and then once again compiles.
Happens in varied scenarios with compiler mode MIXED, e.g.
Single expression instance, used frequently, with different "root" object classes
Example attached, prints out the number of loaded classes when the same expression is repeatedly evaluated for just 2 types of root object (simplest case).
One possible solution might be to have the SpelCompiler "store" classes for specific bytecode and check for identical bytecode generated (excepting compiled expression classname), returning the class that matches the bytecode instead of "defining" it again.
I have been unable to implement anything like this by extending as the structure of the code doesn't seem to provide the relevant hook points (in 4.1.6).