Kode / Kha

Ultra-portable, high performance, open source multimedia framework.
http://kha.tech
zlib License
1.49k stars 174 forks source link

linux native memory leak #1358

Closed sh-dave closed 3 years ago

sh-dave commented 3 years ago

Describe the bug In the provided sample below, some memory of the images doesn't get freed. When i let it run for 2min, 4gb will be allocated. With an older Kha (still Kore based) it will run with a steady 223mb allocated.

To Reproduce

Dump 5 png's named atlas0.png into the assets folder (use big ones, so you see the allocs easier) and run this. It will periodically load and unload these images.

class Main {
    public static function main() {
        kha.System.start({}, function( wnd ) {
            kha.Scheduler.addTimeTask(randomly_load_unload, 0, 0.25);
        });
    }

    static final images: Array<kha.Image> = [];

    // new kha: 4gb after 2min
    // old kha (still kore based): steady 223mb
    static function randomly_load_unload() {
        final ext = #if kha_cpp 'k' #else 'png' #end;
        final url = 'atlas${Std.random(5)}.${ext}';

        kha.Assets.loadImageFromPath(url, false, function( img ) {
            trace('loaded $url');

            images.push(img);

            if (images.length > 4) {
                images.shift().unload();
            }
        });
    }
}

Execution Environment:

Additional context

https://github.com/Kode/Kha/blob/b0af8cc23f6575166862c10fff4fb803fdcc7e04/Backends/Kinc-hxcpp/kha/LoaderImpl.hx#L184-L187

I'm not quite sure, but i think this needs an else, as kinc_image_destroy doesn't actually free the memory for some reason, and it will be lost when the image isn't readable?

else {
    free(kincImage.data);
}
RobDangerous commented 3 years ago

Indeed. It's allocated in loader.c and before Kore's Image-destructor destroyed it even though it didn't allocate it. Put in a variation of your fix.