GameMaker path_delete not working 100%?

S

SirChibi

Guest
I have a game that I am working on and recently started to play around with paths. I however, noticed that my game started to stutter over time and it just get worse and worse. I think I have narrowed down the issue to the path_delete function.

At first I was creating paths in a list using path_duplicate similar to this:

ds_list_add(testList, path_duplicate(testPath));

I then after some code would delete the list and noticed my game started to fall apart after a short time. so I thought that I needed to delete each path in the list one by one, like so:

for(var i = 0; i < ds_list_size(testList)l i++){
path_delete(ds_list_find_value(testList, i));
}

This didn't seem to help the issues though. I was still having a memory leak. After a lot of debugging and testing around I ended up creating a new project and added in some small test code of this:

for(var i = 0; i < 100; i++){
var test = path_add();
path_delete(test);
}

Using the debugger and the debugging graphs I can see the the memory leak is really bad with this code, I even tested the code without the loop and its still there, it's just a lot slower. I am not fully understanding why this code is causing issues and would love any help. I am very new to these forums so I hope I am correctly posting.

TLDR:

var test = path_add();
path_delete(test);

Is causing a memory leak, and I don't know why.
 

TsukaYuriko

☄️
Forum Staff
Moderator
Memory leaks do not degrade performance - at least not until you overflow your RAM and end up on the pagefile. Most likely, your game would crash due to running out of RAM long before that happens.

That aside, when you delete resources, that does not mean that the memory that was in use will instantly be freed. It will more likely remain reserved but not in actual use, and may be freed at any later point in time.


If the problem you're facing is performance degradation, the metric in the debugger that you should be looking at is the profiler, not the memory usage. Using the profiler, collect some data about what is using how much processing power while the game is in undergoing the procedure you described above and let us know the results.
 
Hi there, you can read what I found out from testing below, but first, my question is, how many paths are you creating during your game, and if it's a large amount, is it necessary to create and delete so many paths. Could you re-use paths instead?

My findings:

I don't think memory is the biggest issue here.

I also can't isolate path_delete() as being the problem, because I tested this with and without using path_delete() and got similar results.

What I did find, is that at a certain number of paths having been created, there is a major lag creating new paths. Memory Page faults within Windows Task Manager also increase significantly at this point.

I also noted that unlike some other dynamic resources such as ds_lists for example, path indexes are not re-used, they simply keep incrementing.

Here's the details:

I can create up to 100,000 paths in chunks of 10,000 paths at a time without too much trouble. Each subsequent group of 10,000 paths that I create *does* take slightly longer as the amount of paths created increases.

Memory usage only increased 15Mb to 20Mb though.

When the total path count is below 100,000, creating an additional 10,000 paths in a loop takes a fraction of a second.

The most significant lag happens after I've created around 128,000 paths. Creating another 10,000 takes a few seconds, during which GMS 2 is unresponsive due to executing the loop.

What I noticed in Windows Task Manager, is that the number of page faults increases dramatically after hitting the 128,000 mark.

Initial RAM Usage at start with no paths : 27,376K

128,000 paths / 45,000 page faults total
131,000 paths / 297,065 page faults total
132,000 paths / 555,065 page faults total
142,000 paths / 3,246,496 page faults total
152,000 paths / 6,131,189 page faults total
164,000 paths / 9,854,787 page faults total / RAM usage : 40,584K

If I delete the paths as I go, memory usage at 164,000 paths is 28,092K.

(This RAM usage is from task manager. In the GMS profiler, RAM usage started at 6.76Mb, and finished at 9.36Mb)

FPS stayed at a solid 5000 fps approx. (when not in the process of creating paths)
 

TsukaYuriko

☄️
Forum Staff
Moderator
Are we perhaps dealing with another case of linked lists being used for dynamic resource IDs here? There was a long discussion about this on either the old GMC or this one, but regarding instances, which were lagging out games in a similar fashion due to internally using a linked list (which implied that access times for the latest instance would rise according to how many instances there are in total, and scale anywhere in between). I suggest filing a bug report about this... I can't imagine many projects that would need to concurrently use 128k lists, but this seems odd nonetheless.
 
Are we perhaps dealing with another case of linked lists being used for dynamic resource IDs here? There was a long discussion about this on either the old GMC or this one, but regarding instances, which were lagging out games in a similar fashion due to internally using a linked list (which implied that access times for the latest instance would rise according to how many instances there are in total, and scale anywhere in between). I suggest filing a bug report about this... I can't imagine many projects that would need to concurrently use 128k lists, but this seems odd nonetheless.
That would probably explain it, traversing the list gradually takes more time the larger it gets.

I've submitted a bug report via the helpdesk, the ticket number they emailed me is 164013.
 
S

SirChibi

Guest
Hi there, you can read what I found out from testing below, but first, my question is, how many paths are you creating during your game, and if it's a large amount, is it necessary to create and delete so many paths. Could you re-use paths instead?

My findings:

I don't think memory is the biggest issue here.

I also can't isolate path_delete() as being the problem, because I tested this with and without using path_delete() and got similar results.

What I did find, is that at a certain number of paths having been created, there is a major lag creating new paths. Memory Page faults within Windows Task Manager also increase significantly at this point.

I also noted that unlike some other dynamic resources such as ds_lists for example, path indexes are not re-used, they simply keep incrementing.

Here's the details:

I can create up to 100,000 paths in chunks of 10,000 paths at a time without too much trouble. Each subsequent group of 10,000 paths that I create *does* take slightly longer as the amount of paths created increases.

Memory usage only increased 15Mb to 20Mb though.

When the total path count is below 100,000, creating an additional 10,000 paths in a loop takes a fraction of a second.

The most significant lag happens after I've created around 128,000 paths. Creating another 10,000 takes a few seconds, during which GMS 2 is unresponsive due to executing the loop.

What I noticed in Windows Task Manager, is that the number of page faults increases dramatically after hitting the 128,000 mark.

Initial RAM Usage at start with no paths : 27,376K

128,000 paths / 45,000 page faults total
131,000 paths / 297,065 page faults total
132,000 paths / 555,065 page faults total
142,000 paths / 3,246,496 page faults total
152,000 paths / 6,131,189 page faults total
164,000 paths / 9,854,787 page faults total / RAM usage : 40,584K

If I delete the paths as I go, memory usage at 164,000 paths is 28,092K.

(This RAM usage is from task manager. In the GMS profiler, RAM usage started at 6.76Mb, and finished at 9.36Mb)

FPS stayed at a solid 5000 fps approx. (when not in the process of creating paths)
I had thought about reusing paths instead of doing what I was doing, which was creating like greater than 100 paths per step, I just found this issue and got hung up on it. Thank you for all the testing and the help, I greatly appreciate it. I will just edit my code to reuse paths which shouldn't be too hard.

Are we perhaps dealing with another case of linked lists being used for dynamic resource IDs here? There was a long discussion about this on either the old GMC or this one, but regarding instances, which were lagging out games in a similar fashion due to internally using a linked list (which implied that access times for the latest instance would rise according to how many instances there are in total, and scale anywhere in between). I suggest filing a bug report about this... I can't imagine many projects that would need to concurrently use 128k lists, but this seems odd nonetheless.
I agree that a game would probably never need that amount but I'm glad we reached somewhat of an answer for this weird issue, it was really confusing me. Thanks for your help!

That would probably explain it, traversing the list gradually takes more time the larger it gets.

I've submitted a bug report via the helpdesk, the ticket number they emailed me is 164013.
Thank you, hopefully something will come of it!
 
Top