Clean JavaFX property listeners and bindings (memory leaks) - binding

I haven't found a simple answer for these two questions:
do I have to remove a listener before deleting the property instance (the listener is not used anywhere else)?
BooleanProperty bool = new SimpleBooleanProperty();
bool.addListener(myListener);
bool.removeListener(myListener); // is it necessary to do this?
bool = null;
do I have to unbind a uni-directional bounded property before deleting the property instance?
BooleanProperty bool = new SimpleBooleanProperty();
bool.bind(otherBool);
bool.unbind(); // is it necessary to do this?
bool = null;

Case 1
Given that myListener "is not used anywhere else" and therefore I assume, a [method-] local variable, the answer is no. In the general case though, the answer is mostly a no but can sometimes be a yes.
As long as myListener is strongly reachable, then it will never become eligible for finalization and it will continue to consume memory. For example, this would be the case if myListener is a "normally" declared static variable (*all "normal" references in Java are strong references*). However, if myListener is a local variable, then the object will not be reachable anymore after the return of the current method call and bool.removeListener(myListener) is a bit meaningless over-engineering. Both the observer and the Observable goes out of scope and will eventually be finalized. A quote from my own blog post about this answer might paint a better picture:
It doesn’t matter if the box know about the cat inside of it, if you
throw the box into the ocean. If the box isn't reachable, nor is the
cat.
Theory
To fully understand the situation here, we have to remind ourselves of the life-cycle of a Java object (source):
An object is strongly reachable if it can be reached by some thread
without traversing any reference objects. A newly-created object is
strongly reachable by the thread that created it. [..] An object is
weakly reachable if it is [not] strongly [..] reachable but can be
reached by traversing a weak reference. When the weak references to a
weakly-reachable object are cleared, the object becomes eligible for
finalization.
In the case of static variables, these will always be accessible as long as the class is loaded, thus reachable. If we didn't want a static reference to be the one that hinder the garbage collector to do his job, then we could declare the variable to use a WeakReference instead. JavaDoc says:
Weak reference objects [..] do not prevent their referents from being
made finalizable, finalized, and then reclaimed. [..] Suppose that the
garbage collector determines at a certain point in time that an object
is weakly reachable. At that time it will atomically clear all weak
references to that object [..]. At the same time it will declare all
of the formerly weakly-reachable objects to be finalizable.
Explicit management
For illustration, let's assume that we write a JavaFX space simulation game. Whenever an Observable planet moves into the view of a spaceship observer, the game engine register the spaceship with the planet. It is quite apparent that whenever the planet goes out of view, the game engine should also remove the spaceship as an observer of the planet by using Observable.removeListener(). Otherwise, as the spaceship continues to fly through space, memory will leak. Eventually, the game cannot handle five billion observed planets and it will crash with an OutOfMemoryError.
Do note that for the vast majority of JavaFX listeners and event handlers, their life-cycle is parallel to that of their Observable so the application developer has nothing to worry about. For example, we might construct a TextField and register with the text field's textProperty a listener that validate user input. As long as the text field sticks around, we want the listener to stick around. Sooner or later, the text field is not used anymore and when he is garbage collected, the validation listener is also garbage collected.
Automatic management
To continue on the space simulation example, assume that our game has limited multiplayer support and all the players need to observe each other. Perhaps each player keep a local score board of kill metrics or perhaps they need to observe broadcasted chat messages. The reason is not the important point here. What would happen when a player quit the game? Clearly, if the listeners are not explicitly managed (removed), then the player who quit will not become eligible for finalization. The other player's will keep a strong reference to the offline player. Explicit removal of the listeners would still be a valid option and probably the most preferred choice for our game, but let's say that it feels a bit obtrusive and we want to find a more slick solution.
We know that the game engine keep strong references to all players online, for as long as they are online. So we want the spaceships to listen for changes or events of each other only for as long as the game engine keep the strong references. If you read the "theory" section, then surely a WeakReference sounds like a solution.
However, just wrapping something in a WeakReference is not the entire solution. It seldom is. It is true that when the last strong reference to the "referent" is set to null or otherwise become unreachable, the referent will be eligible for garbage collection (assuming that the referent cannot be reached using a SoftReference). But the WeakReference is still hanging around. The application developer need to add some plumbing so that the WeakReference itself is removed from the data structure he was put in. If not, then we might have reduced the severity of the memory leak but a memory leak will still be present because dynamically added weak references consume memory too.
Lucky for us, JavaFX added interface WeakListener and class WeakEventHandler as a mechanism for "automatic removal". The constructors of all related classes accept the real listener/handler as provided by client code, but they store the listener/handler using a weak reference.
If you look at the JavaDoc of WeakEventHandler, you'll notice that the class implement EventHandler, so the WeakEventHandler can be used wherever an EventHandler is expected. Likewise, a known implementation of a WeakListener can be used wherever an InvalidationListener or a ChangeListener is expected.
If you look into the source code of WeakEventHandler, you'll notice that the class is basically only a wrapper. When his referent (the real event handler) is garbage collected, the WeakEventHandler "stop working" by not doing anything at all when WeakEventHandler.handle() is called. The WeakEventHandler doesn't know about which object he has been hooked up with, and even if he did, the removal of an event handler is not homogeneous. All known implementing classes of WeakListener has a competitive advantage though. When their callbacks are invoked, they are implicitly or explicitly provided a reference to the Observable they are registered with. So when the referent of a WeakListener is garbage collected, eventually the WeakListener implementation will make sure that the WeakListener itself is removed from the Observable.
If it is isn't already clear, the solution for our space simulation game would be to let the game engine use strong references to all online spaceships. When a spaceship goes online, all other online spaceships are registered with the new player using a weak listener such as WeakInvalidationListener. When a player goes offline, the game engine remove his strong reference to the player and the player will become eligible for garbage collection. The game engine doesn't have to bother about explicit removal of the offline player as a listener of the other players.
Case 2
No. To better understand what I'll say next, please read my case 1 answer first.
BooleanPropertyBase store a strong reference to otherBool. This in itself does not cause otherBool to always be reachable and thus potentially cause a memory leak. When bool becomes unreachable, then so do all its stored references (assuming they are not stored anywhere else).
BooleanPropertyBase also works by adding itself as an Observer of the property you bind it to. However, it does so by wrapping itself in a class that works almost exactly like the WeakListeners described in my case 1 answer. So once you nullify bool, it will be only a matter of time before it is removed from otherBool.

I completely agree with the case 1 answer, but the case 2 is a bit more tricky. The bool.unbind() call is necessary. If ommitted, it does cause a small memory leak.
If you run the following loop, the application will eventually run out of memory.
BooleanProperty p1 = new SimpleBooleanProperty();
while(true) {
BooleanProperty p2 = new SimpleBooleanProperty();
p2.bind(p1)
}
The BooleanPropertyBase, intenally, does not use a real WeakListener (an implementation of the WeakListener interface), it is using a half-baked solution. All the "p2" instances get eventually garbage-collected, but a listener holding an empty WeakReference remains in the memory forever for each "p2". The same holds for all properties, not only BooleanPropertyBase. It's explained here in detail, and they say it is fixed in Java 9.
In most cases, you do not notice this memory leak, because it leaves only a few dozen bytes for every binding that has not been unbound. But in some cases it caused me real trouble. An good example are table cells of a table that gets frequently updated. The cells then re-bind to different properties all the time, and these left-overs in the memory accumulate quickly.

Related

Does dart reuse memory for previously used instances?

It is hard to find a good heading for this, but i think my problem comes clear if i post a small code snipped:
SomeObject instance = SomeObject(importantParameter);
// -> "instance" is now a reference to the instance somewhere in RAM
instance = SomeObject(anotherImportantParameter);
// -> "instance" is now a reference to a different instance somewhere in RAM
My question is now, is the used RAM that was allocated at the first construction reused at the second construction? Or is the RAM of the first instance marked as unused for the garbage collector and the second construction is done with a completely new instance with a different portion of RAM?
If the first is true, what with this:
while(true) {
final SomeObject instance = SomeObject(importantParameter);
}
Will then, each time the while is repeated, the RAM be reused?
It's unspecified. The answer is a resounding "maybe".
The language specification never says what happens to unreachable objects, since it's unobservable to the program. (That's what being unreachable means).
In practice, the native Dart implementation uses a generational garbage collector.
The default behavior would be to allocate a new object in "new-space" and overwrite the reference to the previous object. That makes the previous object unreachable (as long as you haven't store other references to it), and it can therefore be garbage collected. If you really go through objects quickly, that will be cheap, since the unreachable object is completely ignored on the next new-space garbage collection.
Allocating a lot of short-lived objects still has an overhead since it causes new-space GC to happen more often, even if the individual objects don't themselves cost anything.
There is also a number of optimization that may change this behavior.
If your object is sufficiently simple and the compiler can see that no reference to it ever escapes, or is used in an identical check, or ... any other number of relevant restrictions, then it might "allocation sink" the object. That means it never actually allocates the object, it just stores the contents somewhere, perhaps even on the stack, and it also inlines the methods so they refer to the data directly instead of going through a this pointer.
In that case, your code may actually reuse the memory of the previous object, because the compiler recognizes that it can.
Do not try to predict whether an optimization like this happens. The requirements can change at any time. Just write code that is correct and not unnecessarily complex, then the compiler will do its best to optimize in all the ways that it can.

Sprite-kit game lifecycle, properties and global variable?

In my sprite-Kit game, my game goes through the various scenes, across which I want certain variables to be available. See the following diagram:
So the title screen loads the main game screen. When the 'wave' is finished (all objective complete or all lives lost), the end scene is presented with some stats. Then if the player has lives left the main game is loaded again, if not the title screen is presented again.
I want the player's score and number of lives left to be available across the main game scene and the end scene; the high score should be kept across all scenes.
I'm using global variables for these, whereas most of my variables are properties defined under the class.
The first time I had to do this (for my score property before I added a high score or multiple lives) I used a score property on every scene and passed it between scenes when I did the presentScene for the next scene, but that seemed clumsy, especially when I had to add more variables.
Is there a best practice for this i.e. should global variables be used/not be used and if not, is there a correct way to handle properties, perhaps controlled by where you initialise them e.g. in init compared to didMoveToView, which determines if they are re-initiialised when the scene is shown again?
EDIT:
Am I doing something 'wrong' when I go from the End Wave Scene back into the Main Game Screen that is causing the main screen to be re-initialised again? Is there a way to preserve it (with all it's properties) so it isn't fully re-initialied but it's didMoveToView is called again?
I know that many people work with generalized rules like "Don't use globals" or "Singletons are evil". These words of wisdom may be applicable at times, however another way of looking at them would be as tools to make you more efficient in getting your game finished.
There are times when globals/singletons are useful. Games and embedded systems play by different rules than conventional applications. These are typically resource constrained "applications" coupled with performance requirements. Globals are more common than you think in each. Singletons are also commonly in use. I've worked on both embedded systems and games and can say that on every project I've worked on, they've employed either globals, singletons, or both.
In practice, I use singletons over globals. Mainly because I don't have to worry about where to shove the global and what header file it belongs in. Note, the basis as to the why will differ from all you Swifties. For me this stuff is done in primarly in C++ with some Obj-C and a smattering here and there of Swift.
The need to manage game lifecycle is independent of SpriteKit. Many of the SpriteKit posts I see on SO have the devs embedding game state into the scene or VC. They are usually faced with some dilemma on how to move state to the next scene. While this approach may be good for what I will call "local state" (ie. state for the current screen, stage, etc), it is not good for global game state. For example, if you transition from a main screen to an option screen then back to main and then in the game, how are you tracking the changes to those options (eg. changing game difficulty)? Yes you certainly can pass around dictionaries, structs, or what have you around. But at some point of time, you are going to discover that having one common and convenient dumping ground for it all is more convenient. This "dumping ground" would be globals/singletons.
Now before ya'll start yelling at me, there is a catch to all this crazy talk of globals and singletons. I'm not saying create alot of globals/singletons. Rather, be controlled aboutwhen/if you employ globals/singletons.
I'm not talking a gazillion if 'em. I'm talking like one (although I usually have a handful in use). Enter our ficticious friend, the GameManager.
Let's walk down a very simple scenario of a space shooter. Say I have multiple screens such as the title screen, main screen, the in game screen, and the end wave screen. There are certain bits of information that are useful to be passed to the different screens. For example high score or even current score. Those may be values that you want to display on various screens/scenes. So where do you store the score? How do I pass the score between them? For example, if the last high score is displayed on all screens, where do I keep that value?
class GameManager : NSObject {
// Overall game state, GameState is probably some enum
var state:GameState
var lastState:GameState
// Sometimes tracking scenes is useful
var currentScene:SKScene?
var nextScene:SKScene? // Sometimes helpful if you need to construct the next scene and it takes a non-trivial amount of time
// These are the globals we need to share to different "parts" of the game
var score: UInt
var highscore: UInt
var lives: Uint
var stage: Uint
var highscores:[Uint] // A list of all the high score for the user. You would probably want HS based on other users too
// Egads a singleton!
static let sharedInstance = GameManager()
}
If this was a global, it would have some global definition of the instance outside any scope. Like:
var theGameManager : GameManager
So if you want to udpate the score, you'd do
theGameManager.score += 100
If it was a singleton updating the score would look something like:
GameManager.sharedInstance.score += 100
Okay the singleton syntax is a little longer, but perhaps a little less cryptic than the global as to where/what this is.
But now here is where you can have a little more power in things. Let's say when you add a score, every multiple of 100000 scores you an extra life. I can now easily leverage the setter and use that setter to also reward the extra life.
For example this:
GameManager.sharedInstance.score += 100 // the magic of the 100000 for extra life happens automagically in the setter
versus something potentially like this:
myScore += 100
// Do logic to find out if we get an extra life.
// Is this done in a method and if so where does this method live?
// Or is it straight up code which will be duplicated?
Code like this which helps manage global game state is all neatly contained within the GameManager. In other words, the GameManager doesn't just maintain values, but it also provides a way of encapsulating functionality around those values.
Hmm, it seems the currentScene is also here? Why would that be? The GameManager would also be an excellent way to manage the changing of the scenes. More likely done through the game state. Maybe something like:
GameManager.sharedInstance.gameState = GameOverState
Behind the scenes, the gameState setter can then do the magic of swapping out scenes.
These are but a few examples of the practical nature of this approach.
Regarding the talk of loading/storing, this is can also be done through the GameManager if desired. Although for myself, I typically treat it independently based on some data within the GameManager. And this brings up another distinction. I would typically encapsulate ideas within the GameManager. For example, I would probably have a Player and that would make GameManager look like this:
class GameManager : NSObject {
// Overall game state, GameState is probably some enum
var state:GameState
var lastState:GameState
// Sometimes tracking scenes is useful
var currentScene:SKScene?
var nextScene:SKScene? // Sometimes helpful if you need to construct the next scene and it takes a non-trivial amount of time
// These are the globals we need to share to different "parts" of the game
// Note player state is done through this object. This way I can pass around only player when needed.
var player: Player
var stage: Uint
var highscores:[Uint] // A list of all the high score for the user. You would probably want HS based on other users too
// Egads a singleton!
static let sharedInstance = GameManager()
}
Wait you say; "But I don't like this global/singleton jazz. Why don't I just pass this object through to everyone that needs it." The answer is "you can". But in practice, you'll start to find this becomes tedious. You also may find that you discover you need the GameManager, but the caller never had the GameManager passed to it. This means now you're reworking a few methods to pass this object through.
Soooo are globals/singletons evil? You can be your own judge for it. Everyone will have there solution of choice. And if it works for you, use it. For me, it's a no brainer. The benefits of using it for consistent ease of use in accessing/managing global game state across your implementation make it an obvious choice.
So I'm adding a little more info here for an already long answer to
try clarify a few things.
My choice of singleton or global would be on usage, platform, and language. It is also dependent upon the game code base as well. It is not meant to be a dumping ground of just any data. If utilized, the contents should be carefully considered and when possible, use other containers for the contents (ie. wrap them in classes). So while my first example had player information dangling out (done to more easily convey the idea), in reality I would have PlayerState contain player data. Note this may not be the player in it's entirety, but perhaps some shared info that needs to live beyond the in-game life of the player.
class PlayerState {
var score:Uint
var highscore:Uint
var lives:Uint
}
// Simplified GameManager
class GameManager {
var state:GameState
var lastState:GameState
var player:PlayerState
// Egads a singleton!
static let sharedInstance = GameManager()
}
Additionally, I would end up passing around the PlayerState instance versus expecting code to always grab it through the global/singleton.
So for example I would do this:
func doSomething(playerState:PlayerState) {
var score = playerState.score
// Blah blah blah
}
verus
func doSomething() {
// Whee I have singleton
var score = GameManager.player.score
// Blah blah blah
}
Effectively what I'm doing is using the singleton as anchor points to access data objects more easily and then if needed, pass it around. In other words, While they are being employed, I also do not want my code riddled with GameManager.sharedInstance.
As mentioned, there are certainly a bunch of cons to this approach. One of which is concurrency. However, I will point out that concurrency still can occur with data even if it is not in a global/singleton.
My point of this addition is that game dev (and coding in general) involves a degree of practicality. Not only are you doing a balancing act with the system resources to present your game, but presumably you're making the game for people to play it. And for that to happen you need to get it done. Everyone wants to make a perfect snowflake, but what is the timecost for that perfection? At the start of the answer I indicated this technique is a tool. Globals/singletons won't be for everyone. At the same time, one should also not just blindly follow design mantras. If it can be an effective tool for you and help you finish your game faster, then its worthwhile doing. There will always be another game to write and you can then decide based on experience what worked and what did not.
General rule of thumb: If you can avoid global variables, do so.
Now every node has a mutable dictionary called userData. This is designed to be used to save data to a node.
Upon creation of your new scene, transfer whatever data you need from the old scene.
let scene = SKScene(fileNamed:....)
scene.userData["highscore"] = self.highscore
view.presentScene(scene)
Now in the new scenes didMove(view:) method, you read from said userData
As 0x141E has pointed out, remember you need to initialize userData, since chances are you have a custom class, you could do this in your init methods, just remember to override all designated inits so that you have access to the convenience methods.
Also, as mentioned in the comments between Whirlwind and myself, SKNode is NSCoding compliant, so when you go and save your information, you can save the SKNode as a whole and userData will go along with it.
This means all you would have to do is write an extension for SKNode to save/load the node, and this avoids having to worry about managing another class.
During the execution of a game many things could happen, a game have a crash, the player close the app, internet stops, a node could be paused from a parent (so it will be skipped when a scene processes actions). For this reason I agree with Simone Pistecchia comments: you could prepare a "storage manager" class to load and save to file your player stats, use NSCoding to declare and initialize them, use a Shared Instance class to handle them across the project. With this way you could load and save your vars when you need and show them also out of the game (to your main menu for a "High Scores" scene for example of wherever you want)

Are objects immediately released when a property is allocated a second time?

I am working on an app where I am presenting 100 sentences using AVAudioplayer. Rather than have 100 AVAudioplayer objects I wanted to just have one property and change the object associated with it on the fly. My code boils down to the following (though the lines arent immediately following each other in the actual code):
self.thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url1 error:&error];
self.thePlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url2 error:&error];
Does the object initialized with url1 get released when thePlayer is allocated and initialized a second time with url2, or are both objects only released when the view is dismissed? As I am dealing with 100 sound files I don't want them all hanging around in memory. I'm using ARC
Thanks in advance
In your specific case, guessing at what your code likely includes, the objects will probably be deallocated when you want them to be. That's a lot of "guessing," "likely," and "probably." You really need to understand how the memory management works in order to reason about it.
If the AVAudioPlayer is strongly referenced by anything else, then it won't be released until those strong references are gone. In other words, setting thePlayer won't deallocate the player if something else has a strong reference to it. (That "something" may be some part of the system frameworks, or even itself in some rare cases. It doesn't have to be your code.)
If the AVAudioPlayer has pending autorelease calls on it, then it won't be released until the autorelease pool drains (usually at the end of event loop, which basically means "when your method that UIKit called returns.") For example, if you create a large number of objects in a loop and immediately throw them away, they may or may not be deallocated until the autorelease pool drains. Again, autoreleases may be injected by system frameworks. In practice, this means that the object will usually be deallocated "soon" (in a small fraction of a second), but not necessarily immediately. You can clean up autoreleased objects sooner by using #autoreleasepool blocks, which is sometimes necessary if you create many temporary objects in a loop. This is not needed very often.
But to a first-order approximation, in many of the most common cases, yes, replacing the property will automatically and immediately deallocate the previous object.
It would be useful to show how you declared thePlayer. If they are synthesized properly the memory management would be handled automatically. It appears that you are using "self" to access thePlayer and if so you'd be setting the value through a setter/getter and that would handle the memory management for you. But I also notice that "Self" is capitalized and should not be in order to properly use the setter/getter. For more info on synthesized variables check out: What exactly does #synthesize do?. Note there are some places where you should NOT use self and this link discusses that: How does an underscore in front of a variable in a cocoa objective-c class work?.

Does a TList<TProc>.Clear free all captured variables?

When I have a TList (so, a list of "reference to procedure"), and I Clear it, do all the captured variables used in the anonymous methods get freed, so no leaking occurs?
Ie. is reference counting in effect upon clearing the TList?
Delegate types are reference counted like interfaces (in fact they are implemented as interfaces). That means if they run out of scope the object behind the scenes (you might have seen that ArcRec$xxxx thing mentioned somewhere - that is the class name the compiler generates) gets destroyed. Captured variables are implemented as fields inside that class so they also run out of scope and are getting freed.
However you might pay attention to some circular referencing which might cause a memory leak with captured variables because of some important fact:
If you have multiple anonymous methods inside a single routine/method they all are implemented by one single class (that ArcRec$xxxx thing). So in this case the anonymous method with the longest lifetime might keep another one alive even if that already is out of scope.

Debugging strategies for over-retain in ARC?

I've got some objects that are passed to a lot of different views and controllers in my application. They're not getting deallocated when I expect them to. Obviously there is an errant strong pointer somewhere, but the surface area of where it could be is very large--these objects are moved into and out of a lot of different data structures.
My usual go-to solution here is Leaks (which reports no cycles) and Allocations (which lists 500+ retain/releases for this object). Is there any way to reduce my search space here?
Ideally there would be a tool that would let me type in a pointer and see all the strong references to the object, and I could probably eyeball the list and find the extra reference in about 60 seconds. In fact, there is such a tool -- the Object Graph instrument -- but it's not available for iOS software.
You want the Allocations instrument. To track an individual object type, start the application. You need to create a heapshot at every significant event (I usually create them at points when you've just transitioned to or from a view controller).
Once you've got a heapshot that should have the object you're interested in tracking down, then you should be able to find that object type under the heapshot's disclosure triangle. For each object of that type, you can get a history of what retains and releases have been sent to that object by clicking on the arrow in that object's row.
The simplest method to identify whether there is retain cycle or not by just putting a breakpoint in your controller's dealloc()/deinit()(swift) method and whenever you pop your controller check this methods getting called or not if there is retain cycle present in your controller this methods won't get called.
Swift
deinit {
print("Memory to be released soon")
}
Objective C
- (void)dealloc {
NSlog("Memory to be released soon");
}
If you want to get more details about the strong references and root causes you should go with Instrument as the other answer.

Resources