TorqueScript and memory management
by J "hplus" W · in Torque Game Engine · 09/20/2006 (8:28 pm) · 10 replies
I notice that the documentation and tutorials on TorqueScript are totally quiet on how memory management is done in TorqueScript.
I'm _assuming_ that TorqueScript has no garbage collection, and no reference counting, except for some trivial cases like the string datatype. Thus, anything I create, I have to remember to delete (just like in C++). However, it would be nice to have this assumption validated (or, even better, invalidated!)
And I think it should be mentioned early and up-front in the documentation!
I'm _assuming_ that TorqueScript has no garbage collection, and no reference counting, except for some trivial cases like the string datatype. Thus, anything I create, I have to remember to delete (just like in C++). However, it would be nice to have this assumption validated (or, even better, invalidated!)
And I think it should be mentioned early and up-front in the documentation!
#2
Internally, many aspects of Torque use reference counting as part of the Resource Loader, which is responsible for pretty much all of the resources that can be brought into a game. In general, you don't have to worry about any memory cleanup in TorqueScript because it actually is handled internally--you are just responsible for objects that you don't want around any more being deleted when you want them to be.
Not sure if this answers your specific question or not, but no, we don't expect TorqueScript users to deal with memory management explicitly at all.
09/21/2006 (12:27 am)
Once you create an object, it stays in the simulation until it is expressly deleted. You may have noticed a SimGroup called MissionCleanupGroup, which is a simple set of objects that should be deleted at the end of the mission--one of the last steps of the mission cycle scripts is to delete the MissionCleanUp SimGroup, and since it's a SimGroup, all objects within it are deleted as well.Internally, many aspects of Torque use reference counting as part of the Resource Loader, which is responsible for pretty much all of the resources that can be brought into a game. In general, you don't have to worry about any memory cleanup in TorqueScript because it actually is handled internally--you are just responsible for objects that you don't want around any more being deleted when you want them to be.
Not sure if this answers your specific question or not, but no, we don't expect TorqueScript users to deal with memory management explicitly at all.
#3
Nah. *Local* variables stay for only one function. :) Global variables are permanent and can be deleted via removeVariable () I think. Arrays are too global variables (with a naming convention to make them look like arrays, of course).
09/21/2006 (2:17 am)
Quote:
Variables you don't have to delete, they stay only for that function. Arrays must be deleted to clear them from memory after use. Cheers!
Nah. *Local* variables stay for only one function. :) Global variables are permanent and can be deleted via removeVariable () I think. Arrays are too global variables (with a naming convention to make them look like arrays, of course).
#4
I don't quite understand those semantics.
Are you saying that the "SomeObject" instance will be deleted when the function goes out of scope? I believe not. I believe that only local variables with value semantics are deleted, and the only non-trivial datatype with value semantics would be the string type.
Similarly, if a local variable was destroyed at the end of the function, neither of these examples would "work":
I think what I'm trying to say is: "I'm pretty sure TorqueScript is not garbage collected."
Now, if that is true, then what are the available debugging tools to track down and fix memory leaks that come from script? The Microsoft library has some tools for C++-level leaks, but for TorqueScript, tracing the leaks to allocations in script has to be done at the script level.
I really, REALLY wish these things were addressed in a clear section of the documentation -- they are crucial to any real application development.
09/21/2006 (10:00 am)
Quote:*Local* variables stay for only one function. :) Global variables are permanent and can be deleted via removeVariable () I think.
I don't quite understand those semantics.
function func() {
%myObject = new SomeObject...;
}Are you saying that the "SomeObject" instance will be deleted when the function goes out of scope? I believe not. I believe that only local variables with value semantics are deleted, and the only non-trivial datatype with value semantics would be the string type.
Similarly, if a local variable was destroyed at the end of the function, neither of these examples would "work":
function func() {
%myObject = new SomeObject...;
return %myObject;
}function func() {
%myObject = new SomeObject...;
$globalObject = %myObject;
}I think what I'm trying to say is: "I'm pretty sure TorqueScript is not garbage collected."
Now, if that is true, then what are the available debugging tools to track down and fix memory leaks that come from script? The Microsoft library has some tools for C++-level leaks, but for TorqueScript, tracing the leaks to allocations in script has to be done at the script level.
I really, REALLY wish these things were addressed in a clear section of the documentation -- they are crucial to any real application development.
#5
All variables, and for all intents and purposes, all data in Torque Script is a string. The engine parser is responsible for treating the string data as some actual datatype, based on namespace rules, object ID's, etc. When you say %myObject = new SomeObject, all %myObject contains, is an ID reference to SomeObject. The parser will interpret that ID and then act on the object internally as appropriate. So both the examples you displayed will work, because they are only transferring a numerical string value, not the actual object.
The only data you ever have to worry about cleaning up, is the objects you instantiate from script with the new operator. And managing any objects you create in script, is nothing more complicated then keeping track of (the IDs) of those objects, and deleting them when you don't need them anymore. Once you learn proper usage of SimSets and SimGroups, it's a piece of cake to handle any data management you need in Torque Script. Stephen already explained how this is handled for objects loaded through the standard mission file. There is no other way you can seriously affect memory from Torque Script, so there isn't anything else to worry about.
09/21/2006 (11:34 am)
Like many experienced developers who see Torque Script for the first time, you are making things much more complicated then they really are.All variables, and for all intents and purposes, all data in Torque Script is a string. The engine parser is responsible for treating the string data as some actual datatype, based on namespace rules, object ID's, etc. When you say %myObject = new SomeObject, all %myObject contains, is an ID reference to SomeObject. The parser will interpret that ID and then act on the object internally as appropriate. So both the examples you displayed will work, because they are only transferring a numerical string value, not the actual object.
The only data you ever have to worry about cleaning up, is the objects you instantiate from script with the new operator. And managing any objects you create in script, is nothing more complicated then keeping track of (the IDs) of those objects, and deleting them when you don't need them anymore. Once you learn proper usage of SimSets and SimGroups, it's a piece of cake to handle any data management you need in Torque Script. Stephen already explained how this is handled for objects loaded through the standard mission file. There is no other way you can seriously affect memory from Torque Script, so there isn't anything else to worry about.
#6
Not entirely true. If you keep alot of global variables around you will eventually have to clean up. This is rare but it can happen, so never say never.
09/21/2006 (11:53 am)
Quote:
The only data you ever have to worry about cleaning up, is the objects you instantiate from script with the new operator.
Not entirely true. If you keep alot of global variables around you will eventually have to clean up. This is rare but it can happen, so never say never.
#7
Are you saying that this code won't be a problem?
Because it seems to me as if this would actually create a memory leak of a hundred objects per second. And, because the programmer forgot to add them to a SimGroup, there's no easy way of removing them.
Now, the prorammer might not realize this is a bug until a lot later in the project -- how does the programmer go back and find this problem and fix it? Are you saying there are no diagnosis tools for object creation in TorqueScript?
Again, I think this should be stated up front in the Scripting section of the documentation. Right now, it just talks about why scripting is good.
09/21/2006 (3:04 pm)
Quote:There is no other way you can seriously affect memory from Torque Script, so there isn't anything else to worry about.
Are you saying that this code won't be a problem?
function onTick() {
schedule(10, 0, onTick);
$ref = new SomeObject...;
}Because it seems to me as if this would actually create a memory leak of a hundred objects per second. And, because the programmer forgot to add them to a SimGroup, there's no easy way of removing them.
Now, the prorammer might not realize this is a bug until a lot later in the project -- how does the programmer go back and find this problem and fix it? Are you saying there are no diagnosis tools for object creation in TorqueScript?
Again, I think this should be stated up front in the Scripting section of the documentation. Right now, it just talks about why scripting is good.
#8
Usually you stick things like that in a SimSet somewhere so you can kill them if the level changes, and otherwise let them alone. If you need to know about them you usually get told from C++ when you need to know (e.g., on a contact between projectile and player).
GC is great, but in the context of TS, it's really not that big of a lack, esp. as most of the memory churn in your app - like strings, numbers, etc. - are tracked in a stack and killed when they go out of scope.
GC is much more important when you box your data and/or when you GC _everything_. In Java, saying String foo = "hi!" a million times without GC happening is bad. In TorqueScript, it doesn't really matter as the variable's memory gets resized when you set new things into it - in fact, that scenario would result in constant memory usage.
If you feel like it warrants an article in TDN, by all means, I encourage you to add it, but for most people getting into script it's not historically been a big barrier, so I'm not sure it's appropriate to have a big warning about it in the intro to script documentation.
09/28/2006 (7:38 pm)
If you do that, you'll get what you deserve. One reason TS isn't GC'ed is because you're usually making game objects with it - objects that have important roles in the simulation, like projectiles - and you want them to do their thing w/o you having to do a bunch of explicit tracking logic. So if you make a thousand projectiles, you definitely don't want them getting deleted just because you didn't keep a reference to them.Usually you stick things like that in a SimSet somewhere so you can kill them if the level changes, and otherwise let them alone. If you need to know about them you usually get told from C++ when you need to know (e.g., on a contact between projectile and player).
GC is great, but in the context of TS, it's really not that big of a lack, esp. as most of the memory churn in your app - like strings, numbers, etc. - are tracked in a stack and killed when they go out of scope.
GC is much more important when you box your data and/or when you GC _everything_. In Java, saying String foo = "hi!" a million times without GC happening is bad. In TorqueScript, it doesn't really matter as the variable's memory gets resized when you set new things into it - in fact, that scenario would result in constant memory usage.
If you feel like it warrants an article in TDN, by all means, I encourage you to add it, but for most people getting into script it's not historically been a big barrier, so I'm not sure it's appropriate to have a big warning about it in the intro to script documentation.
#9
Right, and if you call malloc() without calling free(), you get what you deserve, too.
I don't need for TorqueScript to be GC -- making it not GC is a suitable design trade-off. What I would like is any kind of tool that lets me actually measure and track the behavior -- just like we have dmalloc(), or the Microsoft debugging store, or one of a million other C/C++ level leak trackers. If I use these on TorqueScript, they'll tell me the leak comes from "script allocate string" or something -- but that's not entirely useful; I need to know at least the file/line where that memory was allocated (in script).
Yes, I'm used to writing systems that stay up for months. I e, longer than it'll take for the GetTickCount() timer to roll over. That's why I care about robustness, and the tools that help me create it.
09/28/2006 (8:10 pm)
Quote:you'll get what you deserve
Right, and if you call malloc() without calling free(), you get what you deserve, too.
I don't need for TorqueScript to be GC -- making it not GC is a suitable design trade-off. What I would like is any kind of tool that lets me actually measure and track the behavior -- just like we have dmalloc(), or the Microsoft debugging store, or one of a million other C/C++ level leak trackers. If I use these on TorqueScript, they'll tell me the leak comes from "script allocate string" or something -- but that's not entirely useful; I need to know at least the file/line where that memory was allocated (in script).
Yes, I'm used to writing systems that stay up for months. I e, longer than it'll take for the GetTickCount() timer to roll over. That's why I care about robustness, and the tools that help me create it.
#10
09/28/2006 (8:19 pm)
The Torque Memory Manager can probably help you a lot, and it wouldn't be hard to extend the memory manager to track script origin of a given allocation.
Torque Owner Ishbuu
[Ishbuu]