Garbage collection? ?:|

so I’m not sure I understand how garbage collection works this is the first game I have made to publish and I’m trying to work out all the bugs and run on android smoothly which it does the first time I play, after either runs slowly or crashes.

I have a class that maps an array off game objects in grid form. when I call remove on the game objects should this get rid off all event listeners and variables? from what I have read no but I cant seem to work it out.

I would like to remove the class parent class that holds the array too with all its variables and listener but its not having it. :frowning:

any help would be greatly appreciated.

i had a similar problem. mostly with things that is executed inside a Timer.delay(). on my case, i made a function that is called in my code when the scene is not used anymore, it removes manually all event listeners, stop all Timer.delay()m remove all elements from the scene and nullifies all global variables in the class.

not sure if it’s the correct way, but it helped a lot in my case.

In the Flash API, the common cause for memory leaks is an event listener that hasn’t been removed. That’s something you have to do manually, unless in the addEventListener() you set useWeakReference to true.

Looking up the API reference it shows that instance functions can use weak references. The only case where using weak references will cause issues is for inner/nested/anonymous functions – which are poor to read for humans, slow to execute on Flash target, and impossible to debug from an error stack trace.

Another common cause for memory leaks (and I think this is language agnostic) is circular references between instances. So instance A refers to instance B, which refers back to instance A. Since they’re referring to each other, they can’t be garbage collected. In this case, you have to null the references. You can play it safe and null all references in your class’ dispose/destroy functions.

Hope this helps :slight_smile:

Depends how it’s being removed. If you set NULL on them, then they’re just null references. You need to be careful with these, because if you access them when they’re null you will crash.

A saner approach would be to simply remove them from the array, when you do that the garbage collector will cleanup for you. You shouldn’t need to set things to NULL as a result.

Garbage collection is basically automatic memory management. It’s job is to dispose any objects in memory that is no longer being used in the current scope.

So for example, in your main loop, when you remove an object instance from an array, that object technically hasn’t been set to NULL, it’s just that it’s been removed from an array. At the end of the scope, that being the main loop, the garbage collector runs to check the state of the memory at that time.

If the object instance you removed is no longer being used, the garbage collector automatically disposes it. This isn’t an exact representation of how all garbage collectors work, but the principle is roughly the same.

The problem with automatic memory management is that they’re slow and takes away memory management from the developer. For high performance applications, this is simply a no-go, because you want to be able to store memory into the physical RAM as fast as humanely possible, and if you can’t do that because a garbage collector is in the way, it slows games down, it slows down the launch process, and perhaps even slows down the closing process.

Hi there,

@cactusanctuary : sorry but most of the things u r writing r just not quite right:

In the Flash API, the common cause for memory leaks is an event listener that hasn’t been removed. That’s something you have to do manually, unless in the addEventListener() you set useWeakReference to true.

Actually u do NOT necessarily need a removeEventlistener for every addEventlistener. A good explanation can be found here for example: http://gingerbinger.com/2010/07/actionscript-3-0-events-the-myth-of-useweakreference/?2010/07/actionscript-3-0-events-the-myth-of-useweakreference

I agree though, that it is easy to create memory leaks by not explicitly removing eventListeners (especially if u do not 100% understand what happens internally). So it is definitely good practice always to call removeEventListener() manually.

Another common cause for memory leaks (and I think this is language agnostic) is circular references between instances.

This is plainly a false statement. Circular references are not a problem in Actionscript and actually also not in most other garbage collectioned languages I know of. U can read a detailed explanation for actionscript here: http://www.adobe.com/devnet/actionscript/learning/as3-fundamentals/garbage-collection.html . Check paragraph “Mark/Sweep”.

Java does “Mark/Sweep”, so does C# and also Javascript for example. The only languages I know of on top of my head which do memory management solely based on Reference Counting (where circular references becomes a problem) are ObjectiveC, Swift and I think C++ when using Smart pointers (I think, I am not a C++ developer).

@dazed_scoters : I feel ur question is to abstract to give a very helpful answer. The before mentioned link to the grabage collection article for actionscript should be a good readup and it might be helpful. Even though it is for actionscript it should apply to haxe / Openfl as well.

@matulk removing event listeners is one of my rules for working with Flash/OpenFL :slight_smile: So that’s why I phrase it as something to always do. I think we’re on the same page about it!

Hmm interesting read about the garbage collection!! Thanks for sharing it. Now I’m not sure where I had the idea that circular references were bad in Flash, because I don’t know and haven’t worked in any of the languages that use reference counting :sweat: Thank you for correcting me on this!

C and C++ by default have no garbage collector. You can install one manually, but isn’t recommended anyway, for high performance applications like games at least. You should just let the operating system decide what to free, because ultimately, the operating system is going to manage the memory regardless of what you do in high level languages.

I’ve never wrote that C++ has Garbage Collection (and never talked about C). I wrote that with “Smart Pointers” in C++ u can do automatic memory management by “referencing counting” (where circular references can produce memory leaks). Which probably does not fall under the definition of “garbage collection”. Although some people seem to call it that anyway.

Oh, well. That’s probably the confusion, then. Because automatic memory management assumes taking away control from the developer, in which case don’t use smart pointers :wink:

Also, I’m pretty sure industry veterans like Jon Blow also say not to use smart pointers as well, but I have no evidence to support that claim, so I could be completely wrong.

“Memory management,” unfortunately, might well qualify as one of the “most-uncertain and inconsistent things” between various target platforms. So, it would pay well to try, as much as possible, to “play your cards very close to your chest” when designing any game.

For instance: allocate physical resources (and event handlers, etc.) only when your game actually needs them. "Characters that the user can actually see on-screen, right bloody now," and so on. Although you might know the (x,y) “grid coordinates” of a yet-to-be-seen character, that doesn’t mean that you need to allocate resources to him yet. “If he can’t actually generate events, he doesn’t (yet) need an event-handler,” and so on. Likewise: “if a creature has moved well-beyond the field of view, he doesn’t need to keep his handlers,” and so on.

This implies the continued presence of an overseer that is constantly aware of what is, and what is not, within “the realm of immediate (potential) user-interface concern.”

Beyond this, I suggest, "memory-management in a game, probably should not be the purview of an “automatic” garbage-collector. Instead, take direct responsibility for all such things yourself. Since you really don’t know how much computing-power a particular platform “has to spare,” the best rule of thumb just might be to assume that it has none.

I didn’t find where Jonathan Blow talked about smart pointers, but I found some tweets where he discusses garbage collection in general.

Then I looked up “pros and cons of garbage collection,” and found that garbage collectors were about as fast as manual memory management in 1993, and they’ve only gotten better since. (Aside: I assume manual memory management improved too, but garbage collectors probably improved more overall.)

Then there’s this FAQ by a UK software engineering consultancy. It makes some compelling arguments in favor of garbage collection, and debunks arguments against it, including at least one of Jonathan’s:

Here is the obvious thing about garbage collection: You are forcing some algorithm to figure out things about your program’s memory usage that you already knew (or should have known) when writing the program.
-Jonathan Blow

However:

Unless all objects are allocated for precisely one purpose, and referred to from just one place, […] then a piece of code that has finished with an object cannot determine that it is safe to call the destructor; it cannot be certain […] that there is not another piece of code that will try to use the object subsequently.
-Memory Management Reference

Unless you use a very restrictive code structure, there are some things you can’t know when you’re writing the program. Reference counting is the bare minimum to get around this.

I respect that Jonathan Blow is a better developer than I am. But I don’t think he can speak for all game developers when he says he doesn’t like garbage collection, and I especially don’t think you can write off all forms of memory management just because he might have said something bad about smart pointers at one point.

This sentence in particular is the worst advice in this thread. You can manage memory yourself, or use reference counters, or whatever, but whatever you do, don’t ignore it and let the OS will deal with it for you.

The OS will indeed deal with it for you: if your app uses too much memory, the OS will close your app and free all that memory.

You’re violating the rules of optimization:

  1. Don’t.
  2. Don’t… yet.
  3. Profile before optimizing.

You have no idea, before writing the code and profiling it, whether this will be a noticeable improvement. It might even hurt performance because you’re constantly adding and removing sprites. I don’t know, and neither do you until you profile it.

But one thing that is certain is that if you write it that way from the start, your code is going to be harder to maintain. If you write maintainable code, you can optimize it without much trouble. However, if you focus on writing optimized code, it won’t be easy to maintain, and it probably won’t even be optimized.

Perhaps I should have been a bit more specific about my terminology, there. I was actually referencing Casey Muratori’s reference about constructors and destructors, and that it’s bad practice to free resources manually yourself, because you’re wasting the users time.

He mentions in his Handmade Hero, right at the very start (Day 3), he explains the following:

"What a lot of object-oriented programmers like to do is allocate and free their resources, whenever they declare them. They do that, even if there is no need to. […] Some people call it ‘Resource acquisition is initialisation.’ Others might think of it as everything wrapped in a class with a constructor and destructor. […] But as I started shipping more real world applications, and cared about performance, basically what I have found is that that is a very bad way to program. The reason is because what is almost always the case, that things are better acquired and released in aggregate. What that means is instead of thinking of things individually, you always think of them as part of a group that gets handled together. […] When we close our window, Windows will bulk cleanup all of our memory and resources.

“If we put in code that destroys resources, windows etc. before we close, we are wasting the user’s time. […] If you’ve ever had one of those applications, where you try to close it, and it takes a while to close down and you’re like ‘What is going on? All I asked was for you to close.’ Well, honestly, a big cause of that is this kind resource destruction. It thinks it needs to free all its resources manually.”

That’s a fairly large snippet of what Casey said.

Sorry if I came across arrogantly, I never, ever mean to do that.

That makes sense, and I agree: when it’s time to close your app, let the OS handle it.

Interesting. That could also explain why garbage collectors get such good performance.

“If I were a bettin’ man …” (and I am), I would guess that the “slow-down” most likely is not coming from garbage-collection.

Instead, I would hazard that it probably comes from event-handlers that have been registered "in anticipation of their possible eventual (maybe) use."

Such things obviously constitute “wasted time,” and “time is not your friend.” (After all, your potential customer is more likely to have purchased his platform at a supermarket checkout line, than at an Apple store.)

As a human, you are inherently bad at guessing what causes performance issues. Stop trying.

Profiling is your friend; guessing is your enemy.

1 Like