Memory leaks due to TrackableTypes?
Posted: 25 Dec 2016, 05:32
So I've been working on improving the Simulated AI system I started some time back.
One property of this system is it currently creates many, many temporary games as part of its simulation, concurrently with the actual real game that's being played. I've noticed that this results in ever-increasing memory growth and tracked this down to apparent memory leaks as a result of the TrackableTypes system.
I'm not very familiar with the purpose of this system, but as far as I understand, what's happening is as follows:
- There are some static TrackableTypes objects - for example TrackableTypes.StackItemViewType - which means any other objects transitively referenced by these will not be garbage collected.
- It appears these end up referencing a lot of view objects (e.g. StackItemView) over time. Each of which, by virtue of being a TrackableObject holds a "props" object which is an EnumMap that's backed by a 129-entry array.
So, I have a a few concerns / questions about the above:
1. Does it even makes sense to have the static global TrackableTypes? Given that it's possible to have multiple Game objects concurrently (e.g. at the very least in the simulated AI mode behind the scenes), it seems any indexing into these by GameObject ids would not be correct - since each game has a distinct id namespace and there can be multiple objects with the same id if they're in different games. However, maybe I'm misunderstanding something here? (As I've not noticed any behaviour problems because of this.). If my concerns are valid, then a solution would be to have TrackableTypes.StackItemViewType and other similar things that refer to game objects to hang off the Game object instead of being statics. Then, their contents could be garbage collected when the Game is no longer referenced.
2. What's responsible for clearing entries out of those collections? If moving them to be per-Game doesn't make sense, then maybe I just need to make the simulation code forcefully clear them somehow?
3. We should probably switch the TrackableObject's props map to something more memory efficient - as it seems wasteful to have a 129-slot array allocated when most of the time something like 10 properties are set (from inspection). Maybe there's some good map classes in some of the project's dependencies that already solve this problem.
One property of this system is it currently creates many, many temporary games as part of its simulation, concurrently with the actual real game that's being played. I've noticed that this results in ever-increasing memory growth and tracked this down to apparent memory leaks as a result of the TrackableTypes system.
I'm not very familiar with the purpose of this system, but as far as I understand, what's happening is as follows:
- There are some static TrackableTypes objects - for example TrackableTypes.StackItemViewType - which means any other objects transitively referenced by these will not be garbage collected.
- It appears these end up referencing a lot of view objects (e.g. StackItemView) over time. Each of which, by virtue of being a TrackableObject holds a "props" object which is an EnumMap that's backed by a 129-entry array.
So, I have a a few concerns / questions about the above:
1. Does it even makes sense to have the static global TrackableTypes? Given that it's possible to have multiple Game objects concurrently (e.g. at the very least in the simulated AI mode behind the scenes), it seems any indexing into these by GameObject ids would not be correct - since each game has a distinct id namespace and there can be multiple objects with the same id if they're in different games. However, maybe I'm misunderstanding something here? (As I've not noticed any behaviour problems because of this.). If my concerns are valid, then a solution would be to have TrackableTypes.StackItemViewType and other similar things that refer to game objects to hang off the Game object instead of being statics. Then, their contents could be garbage collected when the Game is no longer referenced.
2. What's responsible for clearing entries out of those collections? If moving them to be per-Game doesn't make sense, then maybe I just need to make the simulation code forcefully clear them somehow?
3. We should probably switch the TrackableObject's props map to something more memory efficient - as it seems wasteful to have a 129-slot array allocated when most of the time something like 10 properties are set (from inspection). Maybe there's some good map classes in some of the project's dependencies that already solve this problem.