Debugging memory leaks

Probably the most frequent reason for a memory leak is creating endless ColorBuffer instances without calling .destroy() on them. But it’s not the only one.

I wrote a short function that could help diagnose which resource is growing out of control:

        fun showSessionCounts(session: Session.Companion) {
            fun count(f: Session.() -> Set<*>) = session.stack.sumOf { f(it).size }
            writer {
                box = drawer.bounds.offsetEdges(-50.0)
                text(
                    listOf(
                        "colorBuffers: ${count { colorBuffers }}",
                        "arrayCubemaps: ${count { arrayCubemaps }}",
                        "arrayTextures: ${count { arrayTextures }}",
                        "atomicCounterBuffers: ${count { atomicCounterBuffers }}",
                        "bufferTextures: ${count { bufferTextures }}",
                        "computeShaders: ${count { computeShaders }}",
                        "cubemaps: ${count { cubemaps }}",
                        "depthBuffers: ${count { depthBuffers }}",
                        "indexBuffers: ${count { indexBuffers }}",
                        "renderTargets: ${count { renderTargets }}",
                        "shaderStorageBuffers: ${count { shaderStorageBuffers }}",
                        "shaders: ${count { shaders }}",
                        "vertexBuffers: ${count { vertexBuffers }}",
                        "volumeTextures: ${count { volumeTextures }}",
                    )
                )
            }
        }

You can place this function inside your Program block, then call it inside extend { } with showSessionCounts(Session).

It will display some text like this:

None of those number should grow out of control. If they do, you have now an idea on what to investigate :wink: .

Thanks to this commit, in (future) openrndr versions greater than v0.5.0-alpha2 this will be simpler:

// Log the resource stats to the console
println(Session.statistics)

or

// Render the resource stats as an overlay, like in the image above
writer {
    box = drawer.bounds.offsetEdges(-50.0)
    text(Session.statistics.toString().substringAfter('(').dropLast(1).split(", "))
}
1 Like