GameMaker I think i'm leaking

I "think" I may have a memory leak. I "think" it may be caused by not destroying my ds lists and maps. However the data structures are created under a create event so should only be created one time and used many.

How am I supposed to delete them when I want to be using them actively.

I also have ini file actions but they are run on demand and I believe they are all terminated at the end.

I have never had a leak before. This is one of the most difficult problems I have come across.

Is it possible to find leaks without having a stroke.

Thanks
 
If you are still using the data structures and you are not creating them more than once you most likely do not have a leak. I think you're not understanding what a memory leak is. A memory leak happens if you are losing access to the pointer for a data structure without destroying it first. For instance, if you create a ds_map and store it in a variable called item_info every time you pick up an item, you will have a memory leak because you are not destroying the previous map stored in item_info before creating a new one. If you are simply creating a data structure in the create event of some instance and then using that data structure throughout the game, you will not have a memory leak. Once you are finished using the data structure (let's say the player quits and goes back to the main menu) THEN you should delete it, but it doesn't matter whether the data structure persists for the entire game or you are creating one each step, as long as you are destroying them when you no longer need them/before you reassign the variable the data structure is stored in, you will not have a memory leak.

Explain more about why you think you have a memory leak and perhaps we can help you.
 

TheouAegis

Member
Also the functions room_restart() and game_restart() don't free up those data structures, so those two functions are notorious for leading to memory leaks (hence the cleanup event getting added to GMS2).
 
I am writing a map editor. The status of the tiles (not real tiles but sprites) rotation, location,flip values etc are all stored in lists. The list is then edited when changes happen.

I'm confused because if I destroy the data structure I won't know what data to put back because it's gone.

I think I have a leak because at first I can rotate and add tiles etc but then as time goes on the delay between placing a tile and it being drawn gets slower.

As does all other buttons and other objects.

I hope this explains in more detail. It's difficult to get my head around so I will try to update with a more coherent explanation later today.

Thanks for your help.

PS. if you could provide an example of what would cause a memory leak using lists, That would most probably be of help.

Edit: I can't seem to replicate the issue this morning. I may be talking rubbish. It may need some deeper investigation. However any information you can give me about how leaks are caused in GMS2 and how to prevent them would still be very welcome.

If I where to create a list with one entry, don't destroy it and constantly keep changing the value of that one entry, would this cause a leak in theory?
 
Last edited:
Ok, there is no difference between lists, maps, grids, etc in terms of what can and can't cause a memory leak. If you create multiple data structures, with them all being stored in the same variable, then you will have a leak, i.e.:
Code:
list = ds_list_create(); // Create the first data structure and store it in list
list = ds_list_create(); // Now you've overwritten the pointer to the original data structure with a new one and can no longer access the original list
That will cause a memory leak as you've lost the ability to refer to the original data structure and therefore it will exist until you close down the game, you cannot destroy it anymore. You can also get a memory leak by changing rooms if you are storing the data structure in an instance variable for a non-persistent object, i.e.:

Create Event
Code:
list = ds_list_create();
If you now change rooms, that list is no longer accessible (as the variable storing it's pointer is getting destroyed, but the list itself does not get destroyed) and you will get a memory leak, as you are unable to destroy the list anymore. Finally, as TheouAegis mentioned, using game_restart or room_restart can create a memory leak if you are not using the Clean Up event to destroy your data structures, i.e.:
Code:
list = ds_list_create();
game_restart();
That will cause a memory leak for the same reasons outlined above in the example above.

It sounds to me like you are creating more lists than are necessary (or forgetting to destroy an old list before you create a duplicate "version" of it). Can you post some code so we can see how you are handling the lists, as it seems clear that you are misunderstanding how data structures themselves work. The only way you can have a memory leak is to create data structures and then neglect to destroy them before you lose access to the pointer OR to be creating multiple data structures unnecessarily. The memory you are "leaking" will NOT increase unless you are creating more data structures. So if you are forgetting to destroy a single list but you only actually create that list once, you will have a memory leak but it very likely will not be noticeable and it will not "grow" in size (i.e. the amount of memory that the program is using up will not increase beyond the original creation of the list). If, however, you are forgetting to destroy a list and also creating that list multiple times (for instance, perhaps you have an alarm that creates a list every 60 steps or something) then the memory leak will grow. A memory leak is simply memory being put aside for a something that you cannot clear. If you only create a single data structure, the memory put aside for that data structure will never grow beyond what you are adding into that data structure, so sometimes I think the term "leak" is confusing.

If you need a list for the entire time you are in a room, that is fine, as long as you remember to add the destroy command to the Clean Up event of the instance you are creating the list in, like so:

Clean Up Event
Code:
ds_list_destroy(list);
This will trigger when the instance is destroyed or the room is ended (or the game ends, but clean up of data structures happens automatically on game end). So make sure that the instance that holds the list that you are interested in keeping is around for as long as you need the list to be kept.
 
I think you are right I may be confused about the "leak". I feel a bit more confident this is not a leak now. However I have only one room as of now. I am not restarting or anything. I have no cleanup and only create the lists in the create code and only once. I am also not re assigning as you mentioned.

As soon as it is created it only gets written and read not destroyed or re created in any way.

I can't even re create this problem now anyway. I think it may even have just my PC slowing down in general and I jumped the gun after reading scare stories on the internet about how easy it is to screw the ds lists up.

I have something to look out for now if this does happen.

I have attached a link to my code below. obj_place is where all the action is. The action script also has related code but these actions only happen on a button press.

https://drive.google.com/open?id=1EJlrax17BC5n_PqA87lNZkyQmsxWpUj0

Thank you for the info because even if this is not what I though it was no doubt you have saved me a future head ache when I come to restart rooms etc.
 

TsukaYuriko

☄️
Forum Staff
Moderator
Use a for loop to call ds_exists on all list/map/whatever you are using IDs from 0 to, say, 10000. Output the amount of data structures that actually exist. If this number is continuously growing during usage and the growth is reproducible, you have a memory leak. Otherwise, you don't. Alternatively, watch your game's memory usage grow as you are using the map editor. If the memory usage is not permanently increasing when it shouldn't, you don't have a memory leak by definition.

Destroying data structures you are actively using is nonsense, so don't worry about having to do it.

This does not mean that you aren't facing another problem, but it's important to first know what you're dealing with.

Since the symptom description you provided seems to be mainly on the side of performance issues rather than memory issues, I'd start diagnosing it that way. Having high memory usage will not slow your game down by itself, as any point in RAM has the same access time. (There are edge cases with anything that has growing lookup time the more entries it has which might make it appear like having more in memory will slow things down, but it is not the root cause.)

Run the profiler to find out if there are any obvious performance drop sources.
 
Last edited:
T

Taddio

Guest
It was said briefly, but you need to destroy the stuff you have to in the CLEANUP event, not the Destroy. In the profiler/debugger, you can see exactly how many ds_stuff you have active at any given time
 
Thanks everyone. Your comments have been more than valuable. After investigation, you were all correct. I do not have a memory leak. But I will know what to look out for as I am sure I will get one at some point.
 
That's cool. I have never used a profiler before. So there seems to a be a bit of learning needed here. Ill probably spend the day on this now. Thank you.

Edit: Hold your horses, are you saying that the destroy events only work in the cleanup event as draw functions only work in the draw event.

I did not know that. Thanks again.
 
Last edited:
T

Taddio

Guest
Edit: Hold your horses, are you saying that the destroy events only work in the cleanup event as draw functions only work in the draw event.

I did not know that. Thanks again.
Not quite, it's for freeing memory stuff, not actually destroying instance. Its an "What needs to be freed when this instance is destroyed" kind of event, not actually for using instance_destroy(); (not sure at all that would even work)
 

FrostyCat

Redemption Seeker
Edit: Hold your horses, are you saying that the destroy events only work in the cleanup event as draw functions only work in the draw event.

I did not know that. Thanks again.
That's wrong. "Destroy" and "Free" functions work everywhere as long as what they're trying to release still exists. The main problem is the distinction between what triggers Destroy events and what triggers Cleanup events.

Destroy events are only triggered by explicit calls to instance_destroy() or position_destroy(). They do not run when instances are removed by other causes, particularly when the room changes or restarts. In contrast, Cleanup events always run when instances are removed for any reason. If you attempt to free data structures in the Destroy event (wrong) instead of the Cleanup event (correct), every time you change rooms or restart one you'll create a memory leak for yourself.

I strongly suggest that you read up on what the 6 basic events do. It annoys me to no end how much people whine about good code when it's their fault for putting it in inappropriate spots.
 
You must be patient with people because they may not have fully grasped a particular concept. It's a big universe. Just be kind and be humble to everybody. It's not Tadios fault. Maybe he didn't know. He could be "rubber ducking" himself. :)

I'm sorry if I have misinterpreted your intentions.

Edit: I do appreciate that though. I thought that's how it worked before I had to held my horses. So I do understand.
 
Last edited:
Top