If I eval a class ObA{} create and instance and r...
# scripting
l
If I eval a class ObA{} create and instance and return it then I eval another class ObjB{} create and instance and return in. Do I have to do any clean up? From what I understand between each eval there is access to previous classes that were declared. I don't want access to ObjA declation but I will still use the returned instance. How do I clean up?
i
It depends on what host you're using, but in most cases the script instance is loaded in a dedicated classloader, and is independent from the compilation infrastructure. If you'll drop the compiler stuff, the compilation data will be collected, but the loaded instance will remain. I you're using the same script definition, it is also recommended to share evaluation configuration between different scripts evaluations.
l
Copy code
val engine = ScriptEngineManager().getEngineByExtension("kts")
        assert(engine.eval("true") as Boolean)

        val scriptA = """
            import eco.analytics.normalize.engine.Ctx
            class ObjA : Ctx() {
              override fun ping() : String {
                return "ObjA"
               }
            }
            val objA = ObjA()
            objA
        """.trimIndent()
        val objA = engine.eval(scriptA) as Ctx
        assertThat(objA.ping()).isEqualTo("ObjA")


        val scriptB = """
            import eco.analytics.normalize.engine.Ctx
            class ObjB : Ctx() {
              override fun ping() : String {
               return "ObjB"
              }
            }
            val objB = ObjB()
            objB
        """.trimIndent()
        val objB = engine.eval(scriptB) as Ctx
        assertThat(objB.ping()).isEqualTo("ObjB")
Say I do the above 100 times per day with unique Obj names. Will I get a leak? How do I clean up so I can keep generating object instances indefinitely?
Would it be enough just use the same class name over and over i.e, ObjA. That works but not sure how it works internally, does it override the previous one and therefore "cleans it"?
i
The JSR-223 scripting engine you're using is a REPL, so it keeps the compilation state between invocations (and that means that definition of the
ObjA
is visible from the
ObjB
.) The size added to this state by every compilation depends on the script size and possible additional imports, but generally shouldn't be very big. But it might be considered a leak in some sense. Dropping an engine and creating a new one will reset the state, but if you keep instances of the objects, they may retain some links to that state inside - it s passed indirectly on instance creation in order to support some inner machinery of the JSR-223 REPL. So it is something to investigate, but there is a chance that you'll get a real leak in this scenario. To be able to avoid it you'd need to use a custom scripting host, probably non-REPL one for simplicity. In this case you probably will pay a performance penalty for initializing the compiler for every script compilation, but it will allow you to recycle compiler after the compilation immediately, leaving only evaluation infrastructure (a classloader with dependencies) and the script class instance in memory. You can find examples of custom scripting hosts here - https://github.com/Kotlin/kotlin-script-examples.
l
Thank you for the explanation