View Full Version : Memory management

06-23-2012, 10:57 PM
I was curious if there was a way to view memory management in the console log viewer? I seem to be having a slow frame rate issue and have not really pinned it down to what it is that could be causing a memory leak (besides the fact that my shoddy newbie programming generally sucks).

I have attempted to trim off as much as I could: changing values of existing tables instead of making new ones, recycling entities instead of deleting them and creating new ones, copying entities into maps before the game starts, only using update(step) for entities when necessary and disabling when not needed and using random intervals in schedule calls.

I would like a way to monitor memory usage during runtime and find out where variables and tables are sitting, as far as garbage collection is concerned. I read several Lua articles dealing with memory monitoring, but none of the code blocks I tried yielded results other than errors that I don't comprehend.

Since the issue doesn't raise until over half way through test play, I'm guessing it must be a compounding memory usage problem caused by my code somewhere.

Also, I have noticed an occasional "string too long" error when saving and retrieving VectorToString and StringToVector to (and from) the data manager, but it only occurs when I have a log message that prints out the string/vector in question. Would that also cause a silent leak when the log message is disabled (as if the exception is only caught when using LogMsg)?

Sorry if I sound ignorant. I really am. Any advice would be greatly appreciated! :sweatdrop:

06-28-2012, 07:20 PM
Ok, so I probably put these posts in the wrong place, I apologize for any forum faux pas. But at the risk of seeming pretentious, I decided to share what I have discovered (with references).

Researching the aforementioned issue, I have learned a few things about how Lua's global namespace works, and proper programming practices, which includes optimization of performance. I figured maybe this would be helpful for someone else like me that is trying to learn on their own with apparently nobody willing to assist whatsoever.

According to "Programming in Lua" ALL variables are global scope unless specified as a local (that is, "first-class" variables). Apparently, global variables are BAD.

Global variables are stored in a hash table which is fast but has to match variable names by string which is complex and slows performance considerably in large programs. When the table becomes really long, it can take a while to traverse the whole thing looking for string matches. Local vars are stored by numerical index, which is really fast because it only has to match numeric indices (presumably binary) during the traversal.

This is also intrinsic to Lua's automated garbage collection facilities somehow, which also can slow performance. The effect on memory management has something to do with the ratio of garbage collected to the time it takes to run the next garbage collection. A variable goes to the GC when it runs out of scope or it has no more references. Here's a more in depth look in this article http://bitsquid.blogspot.com/2011/08/fixing-memory-issues-in-lua.html and in http://www.lua.org/pil/11.6.html (www.lua.org). Thus, garbage collecting a global variable takes longer than a local, and presumably is also larger (in Kb), affecting the time/size ratio, unless I am mistaken.

Also, variables that are visible to that namespace only, like the 'm_camelCase' type variables found throughout the examples (usually declared in a handy function called "SetDefaults()"), are also actually stored in the global hash. Please correct me if I am mistaken or misinformed. Perhaps Novashell has a special method to deal with that, but as far as I can tell, those type of variables only visible to the script where they were declared are also considered global by Lua.

Even functions are stored as global vars. But some good news: functions can also be called as local functions, which takes the function pointer to the local index instead of the global hash table. Here's an example from "Programming in Lua": http://www.lua.org/pil/6.2.html

So, starting to fix my frame rate issue, I converted most of my global variables to GameLogic::DataManager objects, hoping for a performance increase. Although I have no clue if it will actually give the desired results, the Novashell Scripting Reference says it's fast, so that's what I have to go on.

I have also wondered about any advantages of using "class" constructs for entity scripts vs. the way entities are scripted as in the Dink example (which is how I modeled most of my scripts).

I still have not yet discovered a method to display the contents of the global hash table, although I did discover gcinfo(), which shows garbage collection (although I was only successful in returning one output instead of the 2 parameters that it supposedly holds). As with most of the code samples I have found, this one was not exactly useful.

In conclusion, to solve performance issues requires proper programming, and I have a lot of rewriting to do it seems.

I would welcome any comments, expansions or corrections regarding this topic.