GMS 2 Buffer Memory Usage

king javo

Member
Hi,

I'm noticing when using buffer_delete() I'm not seeing the memory usage come down. For example, if I create a new buffer using buffer_create() the memory increases by let's say 20 MB. When I delete the buffer using buffer_delete() the memory really doesn't move. Then if I repeat this, the memory keeps increasing by 20 MB.

Does anyone know how this works because I feel as though I'm leaking memory as a result of using buffers?
 

chamaeleon

Member
Hi,

I'm noticing when using buffer_delete() I'm not seeing the memory usage come down. For example, if I create a new buffer using buffer_create() the memory increases by let's say 20 MB. When I delete the buffer using buffer_delete() the memory really doesn't move. Then if I repeat this, the memory keeps increasing by 20 MB.

Does anyone know how this works because I feel as though I'm leaking memory as a result of using buffers?
Do you have a lot of other stuff going on unrelated to this buffer allocation in itself because you're doing it as part of a game project, or is it a project that is only doing this? If you have other things happening between allocations, what you're seeing could possibly be a result of memory fragmentation (other code allocating memory in the previously freed up 20MB block so the next allocation won't fit), and the high watermark you're observing is simply related the highest allocated address on the heap, not actual byte count memory usage. Having said that, it seems unlikely, as eventually your other allocations should end up in the early allocated memory, leaving the buffer allocations to happen roughly in the same memory area.
The code below works for me without going over around 30MB
Create
GML:
buf=undefined;
Step
GML:
if (buf != undefined) {
    buffer_delete(buf);
}
buf = buffer_create(20000000, buffer_fixed, 1);
 

king javo

Member
I'll keep digging, but I haven't found anything that would cause this just yet. I'll also test a simple project as you did to clear my senses! I am loading the buffer with a surface, so not sure if that is an issue??

GML:
if buffer_exists(palette_buffer) buffer_delete(palette_buffer);
palette_buffer = buffer_create(_w*_h*4, buffer_fixed, 4);
buffer_get_surface(palette_buffer, override_surface, buffer_surface_copy, 0, 0);
 

king javo

Member
Just tested it with this and memory was steady. So there must be something else occurring in my project?

CREATE
GML:
w = surface_get_width(application_surface);
h = surface_get_height(application_surface);
buf=undefined;
surf = surface_create(w, h);
STEP
GML:
if (buf != undefined) {
    buffer_delete(buf);
    surface_free(surf);
}
surf = surface_create(w, h);
buf = buffer_create(w*h*4, buffer_fixed, 4);
buffer_get_surface(buf, surf, buffer_surface_copy, 0, 0);
 
Well, one obvious thing, why are you creating the surface twice here? I dunno if it's related to your actual problem because it should really only add any memory once at the create event, but it's an incorrect way to work with surfaces regardless.
 

TheouAegis

Member
Delete that object from your room. Create a new object. Inside the new object, inside it's create event, create a surface and fill the surface. Also create a variable TEST=0. Now make a step event for that object and inside the step event, check if TEST==1, then inside that block create a buffer, copy the surface to that buffer, then delete that buffer. Then make a Keyboard Space PRESSED event and set TEST^=1 inside that. That's it. Put that object in your room, open Windows task manager, then run your game. Do not rely on Game Maker's debugger, trust the OS. Keep an eye on the task manager. Ideally, as soon as you press the spacebar, you should see the memory jump from the first buffer being created. The memory should not increase after that. I'm not saying the memory should ever go down, I'm saying the memory should not increase. just because memory has been allocated for the buffer doesn't mean that memory will be freed up when the buffer is no longer in use. GM has to at some point tell the system it needs more memory for that buffer and the system grants that extra memory to the game to use as it feels. Just because the game no longer needs that memory for the buffer doesn't mean it's going to give the memory back to the system, so the memory that the system gives your game according to the task manager should not increase with each buffer, only with the first buffer.
 
Last edited:

king javo

Member
Well, one obvious thing, why are you creating the surface twice here? I dunno if it's related to your actual problem because it should really only add any memory once at the create event, but it's an incorrect way to work with surfaces regardless.
What's the problem with the way I'm creating the surface? When I run a surface_free on it then it's gone so I have to create it again. What am I missing?
 

TsukaYuriko

☄️
Forum Staff
Moderator
Note that memory usage is not guaranteed to decrease right after freeing something that was using it. Processes may keep memory allocated, but not actively in use, so that it can be re-used if it needs to use more memory soon after deallocating something. Usually, they'll release the memory after a while.

You can test whether you have a memory leak by repeating the same thing over and over, allocating and reallocating memory an infinite amount of times. If you run out of memory doing this, you have a memory leak. If memory usage eventually stabilizes, you don't have a memory leak and the process is just keeping memory allocated for the heck of it.
 
Top