Some questions on how code may influence the GC process - memory-management

1) Does adding a Dispose(), or finalize method, have any impact on making an object be GC'd soon? I ask this as my manager wrote some code, adding a finalize() method, in the hope it would be GC'd.
But I argued that the object has to be "marked" for collection first, if it meets certain criteria.
2) Does writing "o = null" (where o is a ref type) have any impact on making an object be GC'd sooner? Either in C++ or Java/C#.
Thanks

Note, this answer is regarding .NET. I don't know how Java does this, at all.
Let's start with the addition of a finalizer, or rather, what happens when an object without one is collected.
When GC runs, and discovers objects for which there are no rooted references, they're collected.
However, if you add a finalizer to the class, when GC discovers that the object is eligible for collection, it is placed on a list, because it has a finalizer.
This list is processed besides the normal GC, and since the object now has a rooted reference (that list), it is temporarily not eligible for collection. The list is processed by iterating over it and calling all the finalizers. There's lots of details here that I'm glossing over.
Once the finalizer for an object has been called, the object is removed from the list. Sometimes later, when GC again discovers that object, though it still has the finalizer method in its type, the object has been marked so that the finalizer no longer needs to run, and the object is now collected as though it didn't have a finalizer to begin with.
So, actually, adding a finalizer will not make the object be collected sooner, rather it will actually make the object be collected later.
The only way to make an object eligible for collection is to remove all rooted references to it.
Calling Dispose also has no meaning in this regard. Dispose is just a method call, and calling it does in no way mark the object as eligible for collection. If, after calling Dispose, you still have rooted references to the object, it will be left in memory and not collected.
However, if your class has a Dispose method, and a finalizer, the Dispose method typically unregisters the object from finalization. Basically you say "Dispose has now taken care of everything that the finalizer would do, so there's no longer any point in calling the finalizer". If it does this, calling the Dispose method, and then removing all live references to the object, will make it both eligible for collection, and skip the finalization step.
On to your second question.
As I said above, you need to remove all rooted references to the object. A rooted reference is a reference that can be tracked back to something that lives for the duration of the program, be it static fields, local variables on still live call stacks, etc. Once all those are gone, the object is eligible for collection.
But the GC in .NET is really aggressive. The JITter will store information alongside the code telling GC which portions of a method that uses the local variables, and if a variable is no longer used, for instance for the last portion of a method, even though the variable still references an object, that variable is considered to be unnecessary, and thus the object can be collected.
For instance, here:
public void Test()
{
object o = new object();
// do something else
}
In this case, as long as the o variable is no longer used in the method, during that "do something else" code, the object in it can be collected.
The JITter will detect when the program is running in the debugger, and then artificially extend the lifetime of all variables to the end of their scopes, so that you can inspect variables even though they technically aren't considered "live" any more. But when not running in the debugger, that o above isn't explicitly nulled doesn't mean anything, the object can still be collected.
Now, if o was a static field, which lives for much longer than a method call, then yes, explicitly setting it to null will of course help, because now you're removing rooted references to the object.
Also, if the variable is re-used later in the method, you can help make the current object eligible for collection by setting it to null. (note I'm not entirely sure about this, perhaps the JITter can see that the current value is not needed, so it can be collected because later on you overwrite the contents anyway)
So to summarize:
Don't add a finalizer unless you need it
Calling Dispose has no bearing on how soon the object becomes eligible for collection
To "mark" an object as eligible for collection, get rid of all rooted references to it
You can help with collection by explicitly setting variables and fields to null, but for local variables no longer in used by a method, it may not be necessary (but won't hurt)

Java:
1) no, finalize() is called when the garbage collector determines that the object is GC-able - it has no bearing on when GC happens, or whether the object will be GC-ed on a given run. In fact, implementing finalize() delays an object from being GCed - the first GC pass determines that the object is GC-able (i.e. finalize() should be called) and it isn't until the second pass that the object is freed - assuming that the finalizer didn't create a new reference to the object!
2) holding onto references will delay GC, so breaking a reference can allow an object to be GCed earlier if the object holding the reference is still reachable. It's no guarantee that the object will be GCed earlier, though.

Related

C++ std::unique_ptr with STL container

I got a piece of code which uses a std::set to keep a bunch of pointer.
I used this to be sure of that each pointer will present only once in my container.
Then, I heard about std::unique_ptr that ensure the pointer will exists only once in my entire code, and that's exactly what I need.
So my question is quite simple, should I change my container type to std::vector ? Or It won't changes anything leaving a std::set ?
I think the job your set is doing is probably different to unique_ptr.
Your set is likely recording some events, and ensuring that only 1 event is recorded for each object that triggers, using these terms very loosely.
An example might be tracing through a mesh and recording all the nodes that are passed through.
The objects themselves already exist and are owned elsewhere.
The purpose of unique_ptr is to ensure that there is only one owner for a dynamically allocated object, and ensure automatic destruction of the object. Your objects already have owners, they don't need new ones!

Cocoa: Object getting autoreleased when it shouldn't

First, I should say I'm using ARC, so retain is not an option. The object's class is of type NSViewController and has two NSTimers as well as several textfields and buttons. The odd thing is that when the two timers are invalidated, it looks like the object is being released. This is a problem because sometimes I just want to pause or restart them, which means I have to invalidate them, but once I do, the reference is lost, and any message to the object will throw a EXC BAD ACCESS.
I'm not very familiar with memory management or ARC but why is the reference lost depending only on the timers? I mean, just because they're invalidated does not mean I don't need the object anymore.
I've tried declaring the timers as instance variables and properties but nothing changed.
What I really need is for the reference not to be retained, even when both timers are invalidated. What am I doing wrong?
NSTimer retains its target, so if it is the only reference to the object it will be deallocated when the timer is invalidated. You'll have to take ownership of your object, preferably by making it a declared strong property.
Edit: Changed "delegate" to "target";
Yes, you'll have to declare a property and (possibly) an instance variable for it.
The release notes give a good example, there are a couple other good intros around. Make sure that you invalidate the timer if your owner class is ever deallocated, otherwise your view controller will hang around.

Check Value of .NET Handle ^

Here's my situation:
I have .NET wrapper-objects in a C++/CLI layer that hold pointers to unmanaged C++ objects. I've implemented the finalizer so that it deletes the unmanaged memory pointed to by the wrapper-object on garbage-collection and sets the pointer to null.
Here's the problem:
I'm watching the finalizer for the .NET wrapper-object and it gets called twice and tries to delete the same memory twice, indicating that I have somehow created 2 .NET wrapper objects that go out-of-scope, and are garbage collected while I'm still expecting the wrapper object to be in scope (these wrapper objects are getting passed to a VB.NET application).
Here's my question:
Is there anyway for me to check the handle value so that I can confirm where the wrapper objects are getting created (copied or whatever)? Currently I'm looking at the handle values (EG - 0x0014fe80), but I see 3 different values for when the object is created, added to a collection, and deleted. So I'm not sure if the GC is just moving stuff around and this is the same object, or if I'm actually seeing 3 different objects that reference the same unmanaged memory. I would like to resolve the duplicate object copies if possible, but I understand that I will probably want to implement some sort of smart pointer so that this doesn't happen.
Thanks,
Ian
Take a look at this question
Here is an implementation of a scoped_ptr that is noncopyable and has an auto-release mechanism for unmanaged objects, by #Ben Voigt
Yeah, I ended up modifying an auto_ptr class to be a shared pointer to ensure that the unmanaged memory is only deleted once through the smart pointer finalizer. I'm assuming I did something similar to all the other implementations; I created a static dictionary in the auto_ptr template class, using the native pointer value as the key, that is checked every time the finalizer is called to update the count of each item, or delete the memory.

Remove a class instance in Ruby?

I've read the notes on GC happening at an undetermined time after disconnecting any references by instance variables, but would the second line in the delete method be foolish, unnecessary or thorough?
class MyClass
# new instances added to ##instances
...
def delete
##instances.delete(self)
self.instance_variables.each{|v| self.instance_variable_set(v,nil)}
end
end
Unnecessary. If you really want to trigger GC, use GC.start or ObjectSpace.garbage_collect.
And because it can't be recommended often enough, once again:
http://viewsourcecode.org/why/hacking/theFullyUpturnedBin.html
The method delete executes in the scope of the instance that is being removed from the ##instances structure, hence it cannot be garbage collected. Something triggered that method to run, and that something is currently holding a reference to it, therefore it cannot be garbage collected until after the method has returned (and the reference to the object been cleared).
That being said, the second line is completely unnecessary. Even if one of the instance variables pointed back to the object itself the GC is clever enough to figure that out (or rather, it just ignores it since it's not a reference counting collector).
Don't try to manually manage memory, it will not pay off. Whether or not you clear the references to the objects in those instance variables the GC decides when they will be freed. If I interpret the idea of your code example correctly all references to the host object are cleared after delete has run, and in that case it doesn't matter if its instance variables are cleared too, the objects will be just as eligible for garbage collection either way. Objects are GC'ed when they are no longer reachable, it does not matter if other unreachable objects have references to them.

Difference between local and instance variables in ruby

I am working on a script that creates several fairly complex nested hash datastructures and then iterates through them conditionally creating database records. This is a standalone script using active record. After several minutes of running I noticed a significant lag in server responsiveness and discovered that the script, while being set to be nice +19, was enjoying a steady %85 - %90 total server memory.
In this case I am using instance variables simply for readability. It helps knowing what is going to be re-used outside of the loop vs. what won't. Is there a reason to not use instance variables when they are not needed? Are there differences in memory allocation and management between local and instance variables? Would it help setting #variable = nil when its no longer needed?
An instance variable continues to exist for the life of the object that holds it. A local variable exists only within a single method, block or module body.
If you're assuming objects in your object's instance variables will be garbage-collected just because you don't intend to refer to them in the future, that isn't how it works. The garbage collector only knows whether there's a reachable reference to the object — and there is if it's in an instance variable.
Setting #variable = nil destroys the reference to the object that the instance variable once pointed to. When there are no more remaining references to an object, it should be collected by the garbage collector eventually. I say "eventually" because the GC is somewhat unpredictable. However, it's easy to have a memory leak by a "dangling reference" and possibly (depending on how the GC is implemented) circular references. What else refers to this object?

Resources