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.
Related
I was wondering, in VB.NET is:
Using tBrush = New SolidBrush(UseColor)
e.Graphics.FillRectangle(tBrush, someRect)
End Using
equivalent to:
e.Graphics.FillRectangle(New SolidBrush(UseColor), someRect)
?
i.e. in the second case will the SolidBrush be released right after the FillRectangle finishes?
It is true Using blocks create their own scope... but so do method calls, as in the second example. .Net is smart enough to know the brush is not reachable anywhere else. Therefore, considered only in terms of scope, the two options are close enough to not have any meaningful difference.
But scope isn't the big issue here. We also need to talk about disposal.
In the first example, the brush will be disposed as soon as the code block is finished. In the second example the brush merely becomes eligible to be disposed, but the exact time at which that disposal happens is still undetermined.
Usually the dispose will happen fairly quickly, even in the second case, and usually there is enough of this resource it doesn't matter much if it's delayed a little. However, sometimes it can take a while, and with some resource types, or in some environments where there is more contention, any potential delay can be a big problem. And since you don't always control the environment where the code runs, it's a good idea stick with a Using block whenever you have a type that implements IDisposable.
I also need to point out disposal has nothing to do with memory. Again, both samples share a similar scope, and so both will have their memory reclaimed by the garbage collector in similar ways. Rather, the resource governed by the disposal in this sample is the GDI handle used by the brush. Without an explicit disposal, that GDI Handle would only be released when the garbage collector eventually gets around to calling the object's finalizer. That could be a while on a system with low memory pressure, hence the need for a different mechanism (IDisposable + Using) to reclaim it.
Short answer, yes they are equivalent. And yes, the second brush will be released and at some point the garbage collector will get it.
The first one is interesting, though, if you want to use the same brush for several rectangles, instead of instantiating a bunch of brush. You could get a similar result by initiating your brush as a named variable and using it until it's out of scope, if it was preferable to your needs.
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.
**Public Sub ExecuteQuery(ByVal pQueryString As String, Optional ByVal pConn As Odbc.OdbcConnection = Nothing)
Dim Mycmd As New Odbc.OdbcCommand(pQueryString, MyConn)
Mycmd.ExecuteNonQuery()
Mycmd.Dispose()
End Sub**
Here I am Clear the object using Dispose( Mycmd.Dispose()). Can I Use here Nothing ( Mycmd = Nothing? . Which is the Best ?
Please Help Me Sir,
By
Arul.
Dim Mycmd As New Odbc.OdbcCommand(pQueryString, MyConn)
This command stores the reference of object created by New Odbc.OdbcCommand(pQueryString, MyConn) into Mycmd, i.e Mycmd would basically have the address of the newly created object.
now when you do
Mycmd.Dispose()
then it indicates that the use of that newly created object is over and the space allocated to that object can be freed during garbage collection.
but when you do
Set Mycmd = Nothing
then it just remove the reference of the newly created object from Mycmd, it does not mark it for garbage collection.
Oftentimes, .net objects will ask other entities (which may or may not even be on the same computer) to "do something"(*) on their behalf, and such entities will continue doing so unless or until they are told to stop. Such objects should implement IDisposable, and their IDisposable.Dispose routine should notify any and all entities which had been doing something on their behalf, to stop doing so. If all references to an IDisposable object were to disappear without Dispose being called first, some other entities might continue forever in uselessly doing something on behalf of an object which has long since ceased to exist.
(*) That "doing something" could be anything, including blocking other requests to do something. For example, an object might ask the operating system for exclusive access to a file, and the operating system might relay that request to another computer. If the object doesn't notify the OS when it no longer needs access to the file, the server could leave everyone else in the universe locked out of the file indefinitely.
In an effort to minimize problems from entities' perpetually acting on behalf of abandoned objects, .net provides a means by which objects can ask to be notified when they're abandoned. If an object which overrides Object.Finalize() is abandoned, then .net will usually call that object's override of the Finalize() method. This kinda sorta works, mostly, but it should almost never be relied upon. It's very hard to design a class so that Finalize() will always do the right thing and never do the wrong thing. Among other things, if one isn't careful, it's possible for .net to call Finalize() on an object which it determines is going to be abandoned, even while that object is interacting with an outside entity. This will never happen in code which properly calls Dispose on the object, but may happen in code which relies upon Finalize().
If you mean assigning the value Nothing to the object as below:
Set Mycmd = Nothing
This doesn't actually do anything in terms of signaling as object ready for garbage collection, or freeing an object's used resources.
In VB6 setting an object to equal Nothing was the correct way to free the object's resources, but now calling the Dispose method is correct. Where objects do not implement IDisposable, then you can simply leave them.
Garbage collection will then happen in its own time (and would have even without the call to .Dispose() ).
There is not any .nothing() method to release object resource. You can use dispose and nothing to release object resources. But dispose is used when IDisposable interface is implemented. If you are using your custom classes. The .net built in object already has this functionality but it works if your object is having referenced otherwise it will give an error. You can use
command=nothing
for all objects either .net framework or custom. Both release object.
I was experimenting with ways to get rid of some memory leaks within my application the other day when I realized that I know virtually nothing about cleaning up my resources. I did some research, and hoped that just calling the .dispose() would solve all of my problems. We have a table in our database that contains about 65,000 records. Obviously when I fill my dataset from the data adapter, the memory usage can get pretty high. When I called the dispose method on the dataset, I was surprised to find out that NONE of the memory got released. Why did this happen? Clearing the dataset doesn't help either.
IDisposable and thus Dispose is not used to reduced memory pressure, although in some cases it might, but instead used for deterministic cleanup.
Consider this, you construct an object that maintains an active and open connection to your database server. This connection uses resources, both on your machine, and the server.
You could of course just leave the object be when you're done with it, and eventually it'll get picked up by the garbage collector, but suppose you want to make sure at least the resources gets freed, and thus the connection closed, when you're done with it. This is where IDisposable.Dispose comes into play.
It is used to clean up resources managed by the object.
It will, however, not free the managed memory allocated to the object. This is still left to the garbage collector, that will kick in at some later time to do that.
Do you actually have a memory problem, or do you just look at the memory usage in Task Manager or similar and go "that's a bit high."?
If the latter, then you should just leave it be for now. .NET will run garbage collection more often if you have less memory available, so unless you're in a situation where you get, or might suspect you will get soon, a memory overflow condition, you're probably not going to have any problems.
Let me explain what I mean by "run less often".
If you have 8GB of memory in your machine, and only have Windows and Notepad running, most of that memory will be available. When you now run your program, even if it loads minor data blocks into memory, you can keep doing that for a long time, and memory usage will steadily grow. Exactly when the GC will kick in and try to reduce your memory footprint I don't know, but I can almost guarantee you that you will wonder why it gets so high.
Let's just for the sake of the argument say that your program will eventually use 2GB of memory.
Now, if you run your program on a machine that has less memory available, GC will occur more often, and will kick in on a lower limit, which might keep the memory usage below 500MB or possibly even less.
The important part to note here is that in order for you to get an accurate picture of how much memory application actually requires, then you can't rely on Task Manager or similar ways to measure it, you need something more targetted.
Calling Dispose() will only release unmanaged resources, such as file handles, database connections, unmanaged memory, etc. It will not release garbage collected memory.
Garbage collected memory will only get released at the next collection. Usually when the application domain memory is deamed full.
I'm going to point out something here that hasn't been explicitly mentioned: calling Dispose() will only clean up (free) unmanaged resources if the developer of the component has coded it.
What I mean is this: if you suspect you have a memory leak, calling Dispose() is not going to fix it if the original developer has done a lousy job and not correctly freed up unmanaged resources. For a bit more info, check this blog post. Take note of the statement The behaviour of Dispose is defined by the developer.
Some objects will ask one or more other entities to do something on its behalf until further notice, to the detriment of other entities. If an object which did so were to disappear without informing the former entities that their services were no longer needed, those entities would continue to uselessly act on behalf of an object that no longer needed them, to the continuing detriment of other entities that would want to use them.
In many cases, for an object "George" to tell an outside entity "Joe" that its services were no longer needed, George would have to know that its services were no longer needed. There are two normal means via which that can happen in .NET, finalization and IDIsposable.
If an object overrides a method called Finalize, then when the object is created the .NET garbage collector will add it to a list of objects with registered finalizers. If the GC discovers that there exists no rooted reference to the object other than that list, the GC will remove the object from that list and add it to a strongly-rooted queue of objects which should have their Finalize method called as soon as possible. Such an object can then use its Finalize method to inform other entities that their services are no longer required.
Although finalization-based cleanup can sometimes work, there's no guarantee of timeliness. At one point during the design of .net Microsoft may have intended that finalization would be the primary cleanup method, but for a variety of reasons it cannot safely be relied upon.
The other cleanup approach, which should be the focus of one's efforts, is IDisposable. Basically, the idea behind IDisposable is simple: for every object that implements IDisposable, there should be one entity (generally either an object or a nested execution scope) which is responsible for ensuring that that object's IDisposable.Dispose method will get called sometime within the lifetime of the universe (which would imply sometime while a reference to the object still exists), and preferably as soon as code can tell that the object's services will no longer be required.
Note that IDisposable.Dispose generally promises that any outside entities which had been asked to do something on an object's behalf will be told that they no longer need to do so, but such a promise does not imply that the number of entities is non-zero. If an object hasn't asked any outside entities to do anything on its behalf, then delivering a message "all" such entities doesn't require doing anything at all. On the other hand, the fact that a Dispose method may do nothing in some cases doesn't mean that it's guaranteed never to do anything in any case, nor that failure to call it in those cases where it would do something won't have detrimental effects.
I recently saw some VB .NET code as follows:
Dim service = ...
Try
...
service.Close()
Finally
service = Nothing
End Try
Does assigning Nothing to service do anything? If it is a garbage collection issue, I am assuming that when "service" went out of scope the referenced object would be garbage collected and the dispose method called on the object.
It seems to me that assigning this variable Nothing can't really do anything, as there could be another reference to the object around so the reference counts haev to be checked anyways.
It only releases the reference, which may mean that the object is available for garbage collection (there could still be other variables referencing the same object). If the object implements IDisposable, you need to call Dispose explicitly, otherwise you may have a resource leak.
NO!
You're seeing old VB6 code, where assigning Nothing reduced the reference count on COM objects.
In most situations assigning null (Nothing) to a reference makes no difference to garbage collection what so ever.
The garbage collector doesn't care about scope, it only cares about usage. After the point in the code where the object is used the last time, the garbage collector knows that it can collect it because it won't be used any more.
Assigning null to the reference doesn't count as using the object, so the last point of usage is before that code. That means that when you clear the reference the garbage collector may already have collected the object.
(In debug mode though the usage of a variable is expanded to it's scope, so that the debugger can show the value of the variable throughout it's scope.)
Assinging NULL to a reference in .NET does not help to clean the object away. It might help the garbage collector to run a little quicker in some corner cases but that's not important at all. It does not call dispose, either (when dealing with a disposable)
I love to assign NULL anyways to explicitly state that I won't use that other object anymore. So it has much more to do with catching bugs (you'll get a nullreference exception instead of possibly calling into some other object - which might fail or even silently create some side effects.)
So assigning NULL after closing another object (File or whatever) is a "code cleanliness" thing that eases debugging, it's not a help to the garbage collector (except in some really strange corner cases - but when you need to care about that you WILL know more about the garbage collector than you ever wanted to know anyways ...)
As everybody has already said, setting to nothing does not force garbage collection, if you want to force GC then you would be far better to use the using ke word
Using objA As A = New A()
objA.DoSomething()
End Using
You still don't need to set to nothing as the End Using tells the Garbage collection that the object is no longer to be used
It's important to understand in .net (or Java) that a variable, field, or other storage location of class type Foo doesn't hold a Foo. It holds a reference to a Foo. Likewise, a List<Foo> doesn't hold Foos; it holds references to Foos. In many cases, a variable will be known by the programmer to hold the only extant reference to some particular Foo. Unfortunately, the compiler has no general means of knowing whether a storage location holds the only extant reference to an object, or whether it holds one of many.
The main rule about IDisposable is that objects which implements IDisposable should be told they are no longer need sometime between the moment they are in fact no longer needed, and the time that all references to them are abandoned. If an object hasn't been Disposed, and code is about to overwrite the only extant reference to it (either by storing null, or by storing a reference to something else), the object should have its Dispose method called. If there exist other reference to the object, and the holders of those references expect to keep using it, Dispose should not be called. Since the compiler can't tell which situation applies, it doesn't call Dispose but leaves that to the programmer (who hopefully has a better idea of whether or not to call it).