Basically, why is there a finalize destructor in C++/CLI. It seems like the GC, before collecting an object, checks to see if delete was called manually and, if not, call the finalizer. So, why can't the GC just call the normal destructor if delete was not called?
It is for the same reasons that you have a Dispose method and a Finalizer in C#. Roughly speaking, in C++/CLI, the destructor corresponds to Dispose and the Finalilzer corresponds to the finalizer. I say roughly speaking, because C++/CLI implements the Dispose pattern for you. That is, if delete is called (i.e. the destructor is called), it ensures that the finalizer is suppressed. If delete is not
called, then the finalizer will run at GC time.
Just like in C#
within the destructor you are allowed to clean-up managed objects and unmanaged objects.
within the finalizer you are allowed to clean-up only unmanaged objects because at this point in time (when the garbage collector is running), the other managed object that this object references may have already been cleaned up. Thus, (to answer your question), it would be incorrect for the GC to call the destructor (as the destructor could have code that cleans up managed resources).
If you have a finalizer, it is common (and good practice) for the destructor to call the finalizer.
These two links may help as well:
http://msdn.microsoft.com/en-us/library/ms177197(v=vs.90).aspx
https://stackoverflow.com/a/12340581/495262
Related
Which Object Oriented Programming concept is displayed by destructors? For example, overloading shows polymorphism. Please explain the reason for your answer. I could not find this anywhere on the web..
Most of the key OOP concepts are shown by destructors. If we consider those concepts as including Inheritance, Object, Class, Encapsulation, Method, Message Passing, Polymorphism, Abstraction, Composition, Delegation and Open recursion. Then we can show all of them being at play in destructors generally.
Now, generally "destructor" means a method that is defined in a class that is automatically invoked when an object is destroyed*. That obviously covers method, object and class.
Destructors encapsulate clean-up logic. Consider a structure that can point to another structure:
struct SomeStruct
{
SomeStruct* Next;
}
If the above was written in a language that didn't support object-oriented design by letting us define a method on SomeStruct itself, and that deletes heap objects with a global delete() method, then to clean up all the memory used by a SomeStruct we'd need to do something like:
CleanUpSomeStruct(SomeStruct* toDelete)
{
while(toDelete != null)
{
SomeStruct* deleteNext = someStruct->Next;
delete(toDelete);
toDelete = deleteNext;
}
}
Notably:
We have to do the work to clean up SomeStruct outside of SomeStruct.
There's nothing to prevent this being duplicated elsewhere. Perhaps incorrectly.
We have to be able to access Next directly, increasing the number of places we might do something unwise with it.
If we have cases where we shouldn't delete Next, then while that knowledge could be stored in SomeStruct (perhaps an ownsNext field), the logic of acting on that knowledge is external to SomeStruct.
If we have destructors then:
struct SomeStruct
{
SomeStruct* Next;
~SomeStruct()
{
if(Next != null) delete(Next);
}
}
In contrast to the above:
The work to clean up SomeStruct is in SomeStruct, close to other SomeStruct-related code.
It's possible to have a concept of access-control, which can prevent this being duplicated elsewhere.
Likewise, access-control can stop other cases of accessing Next directly, decreasing the number of places we might do something unwise with it.
If we have cases where we shouldn't delete Next, then that logic can be stored in one place internal to SomeStruct.
On the flip side, since encapsulation means that we may not be able to access Next encapsulation means that we have to have destructors to be able to clean up objects (or give the method an explicit "Clean Yourself Up" method, but having to remember to call it every time, and know if it even exists in a given case, and what it's called is a drag). Obviously this example wouldn't matter if we had automatic garbage collection, but in those cases we would similarly need to have destructors of some sort if encapsulation blocked outside code from necessary clean-up task.
Likewise, if we have inheritance, we need to have inheritable destructors that can pass the clean-up task up the line either implicitly or explicitly:
struct SomeOtherStruct : SomeStruct
{
SomeStruct* Prev;
~SomeOtherStruct()
{
if(Prev != null) delete(Prev);
base.~SomeStruct(); // Possibly this would be implicit in that
// the language would automatically make a
// call to a destructor finish with a call
// to any base destructors.
}
}
This also requires that destructors be abstract in the general sense of being part of the abstract model of what an object is (it may not have anything to do with an abstract keyword used to enforce abstraction in other contexts). They must be polymorphic so that delete(Prev) calls the most derived destructor in the object pointed to by Prev whether it is ~SomeStruct(), ~SomeOtherStruct() or the destructor of yet another derived type, so Message Passing/Dynamic Dispatch is used to find the correct implementation of the abstract/virtual destructor. (A language may enforce this, or may allow non-virtual destructors as an optimisation).
Finally destructors interact with encapsulation and open recursion in that they will have to (perhaps implicitly) call the destructors of objects they are composed of, and perhaps call into methods on themselves to do this.
*"when an object is destroyed" is a plainer concept for languages/frameworks using deterministic deletion of objects than those with non-deterministic garbage collection. Generally in the later case "destructor" refers to a method that runs when that non-deterministic collection finally happens (assuming it ever does) but if they have a separate "disposal" method that can be deterministic then it may serve some of the rĂ´les that deterministic destructors serve. In particular while deterministic destructors can be useful in providing for the RAII technique, non-deterministic destructors do not and any use of RAII-like approaches would have to be part of a deterministic disposal.
The practice of freeing up your program resources exists before OOP came to life. Even in old school C, without any objects, you have to free your memory accordingly or you get memory leaks, resource locks or other not nice consequences.
The concept is Garbage Collection. In oop you can relate it with freeing up space that was previously allocated to any object which is no longer needed or deleted.
To quote the wikipedia
In object-oriented programming, a destructor (sometimes shortened to
dtor) is a method which is automatically invoked when the object is
destroyed.
It's role is useful in cleanup, as in freeing up memory space that is longer used by your program anymore. Since most of the modern programming langauge has automatic Garbage Collection, the explicit call to the destructor is no longer needed.
Read about GC and Finalizer for more info.
Hope it helps.
Destructors implement what we know as "Resource Acquisition Is Initialization"
When implementing the using keyword to instantiate an IO.StreamWriter object does that imply that .close is called on the object or .dispose? Or does it matter since once it hits the end using it is out of scope and will be garbage collected anyways?
The using keyword will call Dispose. However, by convention, Dispose and Close should always perform the exact same functionality, and be interchangable.
As such, any resource that is IDisposable but also provides a Close() method, such as Stream derived classes, are fine to use within a using block.
This is addressed in the Framework Design Guidelines explicitly: "it is important that you make the Close implementation identical to Dispose"...
The MSDN help for IDisposable also suggests this: "The implementer of a class that has such a convention might choose to implement a public method with a customized name, such as Close, that calls the Dispose method."
Or does it matter since once it hits the end using it is out of scope and will be garbage collected anyways?
It will not be garbage collected - after it is no longer in scope, and no longer referenced by any objects, it will be eligible for garbage collection. This means that it will (at least if written properly), eventually get cleaned up, but it may not happen for a long time - including not until the program terminates. The using block causes the resource (not the memory), such as the stream, to be closed immediately.
Using only calls Dispose at the end of the scope. However, for classes such as StreamWriter, Dispose ends up calling Close internally.
Or does it matter since once it hits the end using it is out of scope and will be garbage collected anyways?
This is a misconception: the whole reason for the Using block and the Dispose method is that an object is not garbage collected immediately at the end of the scope.
I want to destroy class instance by its own method. For example:
obj = Object()
obj:destroy()
type(obj) == nil
Object is implemented on C. Is it possible?
If it's not possible, Second way is:
_G["obj"] = nil
collectgarbage()
Thanks!
I want to destroy class instance by its own method.
You should avoid this at all costs. Only expose an explicit destructor routine in Lua if you absolutely need to.
The correct way to handle this is to give your Lua C object a metatable with an __gc metamethod. This metamethod will be called right before Lua garbage collects the object.
If you absolutely must use an explicit destructor function (because you want the user to be able to release expensive resources immediately when they're done, without waiting for garbage collection), then you need to do two things:
Do not require the user to explicitly destroy the object. That is, the object should be able to be destroyed either via destructor or via garbage collection.
Do not break the object when it is explicitly destroyed. Every function that takes this object (member functions or free functions) needs to still work if the user called the explicit destruction function. Those functions may do nothing, which is fine. But the program shouldn't crash.
Basically, your object needs to still be in an "alive" state when it was explicitly destroyed. You need to have the object be a zombie: alive, but not very useful. That way, your program will still function even if it doesn't do the right thing.
Simple obj = nil in your example is enough. Note that you do not destroy content of object, you delete a reference that was in the variable obj, making real object somewhere in memory have one less reference and, if it reached 0 references, unreferenced an eligible for GC.
If your object doesn't have some external task to perform on destruction, that's pretty much all you need. Just lose all references by letting them go out of scope or overwriting variables/table members that contain those references with something else or nil. Otherwise you'd need to call object-specific destructor first and only then remove references.
It is not possible to make such a destructor automatically remove all references from everywhere, but at least it can clear object's internal state and set some internal flag that object is no longer usable or ready to be re-initialized.
It is possible, to some degree. You can create a subtable within the object as a private data store. That subtable is managed solely by the object and therefore can only have one reference. If you define a destructor method for the object, then it would delete the respective subtable, making it eligible for garbage collection. Of course, the parent table would still exist, leaving only the methods which do not occupy any significant resources.
Whether this is "good design" is subjective. I am merely offering a solution for the question asked.
I have VS2010 and added a reference to a COM library to my project and VS embedded a primary interop inside the project.
If I reference objects from the COM library and I want to dispose of them quickly without waiting for the GC, is it needed to call ReleaseComObject ?
Marshal.ReleaseComObject provides a way to immediately drop references to this COM object from everywhere it is being consumed within managed code (because it releases the underlying IUnknown from the RCW that is holding it).
As Hans notes, the generally right course is to simply null your object allow the CLR and GC to do the COM object destruction at the appropriate time.
However, in situations where you need immediate action (COM object holds expensive/scarce resources, or perhaps during shutdown where the sequencing is very complex), calling ReleaseComObject can be the right thing to do.
Martyn
There are two types of approaches in terms of cleaning memory.
Reference Counting Algorithms
Garbage Collection
COM components use reference counting algorithm to reclaim memory. Whenever you do not need a reference of a com component you can call it. But Usually my approach is creating a virtual stack and deleting references like the source code below in C#. .NET guarantees as long as RCW is alive COM components is alive. When RCW is garbage collected release method is invoked. It is not necessary to call release in your code. But it does not effect gc cycles.
void DoSth
{
{
RunTimeCallableWrapper area for the code
ReleaseComObject
}
}
As is common knowledge, calls to alloc/copy/retain in Objective-C imply ownership and need to be balanced by a call to autorelease/release. How do you succinctly describe where this should happen? The word "succinct" is key. I can usually use intuition to guide me, but would like an explicit principle in case intuition fails and that can be use in discussions.
Properties simplify the matter (the rule is auto-/release happens in -dealloc and setters), but sometimes properties aren't a viable option (e.g. not everyone uses ObjC 2.0).
Sometimes the release should be in the same block. Other times the alloc/copy/retain happens in one method, which has a corresponding method where the release should occur (e.g. -init and -dealloc). It's this pairing of methods (where a method may be paired with itself) that seems to be key, but how can that be put into words? Also, what cases does the method-pairing notion miss? It doesn't seem to cover where you release properties, as setters are self-paired and -dealloc releases objects that aren't alloc/copy/retained in -init.
It feels like the object model is involved with my difficulty. There doesn't seem to be an element of the model that I can attach retain/release pairing to. Methods transform objects from valid state to valid state and send messages to other objects. The only natural pairings I see are object creation/destruction and method enter/exit.
Background:
This question was inspired by: "NSMutableDictionary does not get added into NSMutableArray". The asker of that question was releasing objects, but in such a way that might cause memory leaks. The alloc/copy/retain calls were generally balanced by releases, but in such a way that could cause memory leaks. The class was a delegate; some members were created in a delegate method (-parser:didStartElement:...) and released in -dealloc rather than in the corresponding (-parser:didEndElement:...) method. In this instance, properties seemed a good solution, but the question still remained of how to handle releasing when properties weren't involved.
Properties simplify the matter (the rule is auto-/release happens in -dealloc and setters), but sometimes properties aren't a viable option (e.g. not everyone uses ObjC 2.0).
This is a misunderstanding of the history of properties. While properties are new, accessors have always been a key part of ObjC. Properties just made it easier to write accessors. If you always use accessors, and you should, than most of these questions go away.
Before we had properties, we used Xcode's built-in accessor-writer (in the Script>Code menu), or with useful tools like Accessorizer to simplify the job (Accessorizer still simplifies property code). Or we just typed a lot of getters and setters by hand.
The question isn't where it should happen, it's when.
Release or autorelease an object if you have created it with +alloc, +new or -copy, or if you have sent it a -retain message.
Send -release when you don't care if the object continues to exist. Send -autorelease if you want to return it from the method you're in, but you don't care what happens to it after that.
I wouldn't say that dealloc is where you would call autorelease. And unless your object, whatever it may be, is linked to the life of a class, it doesn't necessarily need to be kept around for a retain in dealloc.
Here are my rules of thumb. You may do things in other ways.
I use release if the life of the
object I am using is limited to the
routine I am in now. Thus the object
gets created and released in that
routine. This is also the preferred
way if I am creating a lot of objects
in a routine, such as in a loop, and
I might want to release each object
before the next one is created in the
loop.
If the object I created in a method
needs to be passed back to the
caller, but I assume that the use of
the object will be transient and
limited to this run of the runloop, I
use autorelease. Here, I am trying to mimic many of Apple's convenience routines. (Want a quick string to use for a short period? Here you go, don't worry about owning it and it will get disposed appropriately.)
If I believe the object is to be kept
on a semi-permanent basis (like
longer than this run of the runloop),
I use create/new/copy in my method
name so the caller knows that they
are the owner of the object and will
have to release the object.
Any objects that are created by a
class and kept as a property with
retain (whether through the property
declaration or not), I release those
in dealloc (or in viewDidUnload as
appropriate).
Try not to let all this memory management overwhelm you. It is a lot easier than it sounds, and looking at a bunch of Apple's samples, and writing your own (and suffering bugs) will make you understand it better.