SDL no libera RAM del sistema

I create textures like this:

//Create temp SDL_Surface
SDL_Surface* surface = IMG_Load(this->path.c_str());

//If we successfully loaded an image
if (surface)
{
    SDL_DisplayFormatAlpha(surface);

    bounds = GameRectangle(surface->w, surface->h);

    GLuint object(0);

    glGenTextures(1, &object);

    glBindTexture(GL_TEXTURE_2D, object);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels);

    SDL_FreeSurface(surface);

    return object;
}

glDeleteTextures() frees the VRAM properly but the System RAM remains and builds up until the game crashes.

I located it to the SDL_Surface, apparently the surface memory isn't freed.

¿Alguna idea?

preguntado el 28 de agosto de 12 a las 10:08

that's job of the OS to free the RAM, so the solution might be OS-specific -

I'm using Windows 7 Professional 64bit, SP1 -

How are you measuring the memory usage? Bear in mind that just looking at the task list may give you erroneous results --- it's entirely feasible that SDL <i>is</i> freeing the memory, just not handing it back to the system (which can be very hard). This means that you won't see the task list memory usage decrease, but the memory is still available for reuse by your application. -

@DavidGiven "RAM usage builds up until the game crashes (about 300mb/level)" suggests that it's genuinely leaking. -

I'm using Process Explorer, when it reaches about 90% of my physical memory and I load a new level most textures are white and after a while it crashes and gives me different errors, like access violation or stack overflow. -

2 Respuestas

This has nothing to do with OpenGL.

Your call to SDL_DisplayFormatAlpha returns a new SDL_Surface so your original surface is still allocated. This means you will leak a copy of every image.

Deberías hacer algo como:

SDL_Surface* surfaceWithAlpha = SDL_DisplayFormatAlpha(surface);
SDL_FreeSurface(surface);
...rest of code use surfaceWithAlpha 
SDL_FreeSurface(surfaceWithAlpha);

Consulte las documentación.

Respondido 28 ago 12, 12:08

Ah, great call, it works perfectly now. It even reduced the used RAM from 300mb to 30mb. Thanks! - Orujimaru

I wanted to add that it worked unexpectedly in a way. If I used surfaceWithAlpha for the rest of the code, the colors would be distorted. So then I tried removing the SDL_DisplayFormatAlpha(surface), which worked fine for the two first levels but then crashed at the third with no errors given. So I kept SDL_DisplayFormatAlpha(surface) and added SDL_FreeSurface(surfaceWithAlpha) right below it and it now works perfectly. - Orujimaru

I didn't notice at first that a workaround will be enough for you.

Entonces, llamando glTexImage2D, supplying texture size equal to 0 should force OpenGL to free the memory. You can then delete it. If it doesn't work, the leak is in your code.

Respondido 28 ago 12, 11:08

Thanks, where do you suggest I call glTextImage2D and which value is the texture size? Right now I call it once after I have bound the texture: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, surface->w, surface->h, 0, GL_RGBA, GL_UNSIGNED_BYTE, surface->pixels); - Orujimaru

opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml So I believe it would be something like (GL_TEXTURE_2D, 0, anything, 0, 0, 0, anything, anything, 0) - Bartek Banachewicz

glTexImage doesn't seem to cause the copies to RAM because if I changed my code to your example all textures disappear but the memory usage still grows. Please take a look at the snippet I've added to the original question. - Orujimaru

Can you use some custom memory allocator to ensure your code isn't leaking? - Bartek Banachewicz

I located the issue to the SDL_Surface which I only use to bind the texture. Apparently the SDL_FreeSurface doesn't free the memory as I would have thought. - Orujimaru

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.