function DoSomething(UserDefinedClass obj)
{
AnotherUserDefineClass obj1 = new AnotherUserDefineClass();
int nX = 0;
}
function DoSomethingElse()
{
UserDefinedClass obj = new UserDefinedClass();
DoSomething(obj);
}
If I do this “AnotherUserDefineClass *obj1 = new AnotherUserDefineClass();” in C++ then I know that obj1 is a pointer to a chunk of memory on the heap, and that I am entirely responsible for calling “delete obj1” in order to avoid memory leakage.
I know from “int nX = 0;” that the memory associated with nX is automatically created on the stack and that it is automatically deleted when the function terminates - no memory leakage.
In Unity, what exactly is "AnotherUserDefineClass obj1 = new AnotherUserDefineClass(); "doing?
Is it creating a local variable on the stack which is auto deleted or is it allocating a chunk of memory on the heap that I must explicitly delete before the function ends?
And I also think I understand that in “function DoSomething(UserDefinedClass obj)” “UserDefinedClass obj” is the same as “UserDefinedClass &obj” in C++. So any changes you make to obj inside the function will be reflected in the object that was passed to the function as a parameter. Is that correct?
C# is a managed language/runtime environment meaning that you do not need to explicitly delete any allocated memory.
Once all references to an object are gone (the runtime keeps track of references) the object qualifies for “Garbage Collection” (akin to deleted). At some point in time after all references are gone it will be garbage collected. When the garbage collection happens all depends on the garbage collection implementation.
In c# all references to classes are essentially pointers, as such your example:
function DoSomething(UserDefinedClass obj)
is passing the equivalent of a pointer in C++:
void DoSomething(UserDefinedClass *obj)
To be pedantic, a reference in C++ is not the same. As in:
function DoSomething(UserDefinedClass &obj)
A C++ reference is an alias for an instance of an object (and can’t be reassigned/bound to another object). As such a class reference in C# behaves like a pointer in C++, but not a reference.
The subtle difference is that because all class references are pointers in C#, the ‘.’ operator dereferences the pointer. That is, with class references, the ‘.’ operator is the equivalent of the ‘->’ C++ operator.
Note that structs are value types in C# and behave more like int, float, etc. I suggest you do a bit a crash course on C# (which is dead simple for a C++ programmer to learn once you know the differences).
Well the fellow at work, who is also relatively new to Unity, seems to think that "AnotherUserDefineClass obj1 = new AnotherUserDefineClass(); " allocates a chunk of memory on the heap and that, when the function ends, it remains allocated on the heap until the script is unloaded and the Unity garbage collector deletes that chunk of memory.
If that is the case then, to all intents and purposes, it still constitutes memory leakage even if in a more ‘contained’ way than in C++.
As mentioned above, that ‘chunk of heap memory’ qualifies for garbage collection as soon as all references are gone.
But remember garbage collection (GC) is a nasty thing that you want to avoid - it can produce ‘frame rate glitches’ when the GC runs.
Again, you can not assume when the GC will run - it’s an implementation detail. Even calling System.GC.Collect (); is only a ‘request’ there are no guarantees when or if it will run.
To overcome this you avoid allocating (new) frequently, use object pooling, etc to avoid garbage collection. eg, lots of bullets being spawned would use a pool of objects that you’d reuse and not allow them to be GC’d.
Google searching for: Unity avoid garbage collection
You’ve passed a reference of p to SendMessage - it’ll exist while that reference exists. ie, it can’t be GC’d until SendMessage returns as SendMessage still has a reference, therefore can not yet qualify to be GC’d
To be more clear - the lifetime of a class instance is not defined by scope, it’s defined by the number of references to it. This is totally different to how an unmanaged environment works (C++).
No, they’re not identical. One is using reflection to invoke a method named “SomeFunction” where the other is directly calling the method.
SendMessage() is a Unity thing to simplify inter-object communication (but is in fact a terrible thing to use unless you have to).
The point being, that SendMessage() still needs to keep the reference to p so it can pass it onto SomeFunction, so as far as the lifetime of p is concerned, they’re probably the same (I won’t assume what SendMessage is doing internally, but I expect it would not keep a reference to p once it’s invoked SomeFunction).
So SendMessage(“funcname”, p) does not keep the reference to p but my function that calls SendMessage(“funcname”, p) does so that, when funcname(Parameter p) executes, then p will still be pointing to a valid object that has not been garbage collected?
I.E. My function that calls SendMessage(“funcname”, p) wont end until funcname(Parameter p) completes execution?
Otherwise all my “Parameter p new Parameter()” will have to be the equivalent of C++ global.
If you know how c++ heap allocation works then just think of C# being the same but while any reference exists to it anywhere in any form, it will not qualify for garbage collection.
That’s it.
If you’re passing a reference around between methods & classes, those methods & classes need to keep a reference (they need it so they can refer to the thing) and while those references exist so does the object it points to.
So if your object is still referenced by a List, Dictionary, Array, class, struct, anything, then it will not be garbage collected.