utopia-rise / godot-kotlin-jvm

Godot Kotlin JVM Module
MIT License
613 stars 44 forks source link

Scenes with lots of nodes close extremely slowly due to excessive JVM Garbage Collector invocations. #651

Closed ImplementsLegend closed 1 month ago

ImplementsLegend commented 3 months ago

Simple scenario:

class Container:Node(){
    init{
        repeat(1000000){
            addChild(Node())
        }
    }
}

Godot runs absolutely fine, but when you try to close it, it takes forever.

Problem is that MemoryManager.cleanup() method invokes garbage collector too much. (at least once for every 256 objects)

internal object MemoryManager {
    /*omitted*/
    fun cleanUp() {
        /*omitted*/
        var begin = Instant.now()
        while (ObjectDB.any { it != null } || nativeCoreTypeMap.isNotEmpty()) { //loops until all objects are cleaned

            forceJvmGc() //runs JVM Garbage Collector
            if (manageMemory()) { //cleans up to 256 objects
                begin = Instant.now()
            }
            /*omitted*/
    }
}

So, to clean up 1000000 nodes, forceJvmGc() will be invoked approximately 4000 times and that takes a long time.

CedNaru commented 3 months ago

It's a known issue that this part of the code is slow. We plan to replace it following this existing proposal: https://github.com/utopia-rise/godot-kotlin-jvm/issues/508

The direct consequence will be that we won't need to wait for the GC to run when closing Godot anymore.

kostaskougios commented 3 months ago

I am having as well a slow shutdown when closing my game. I am creating a 3d map with a lot of tile-nodes and I am guessing it is this issue.

CedNaru commented 1 month ago

Should be solved by #661