KeepAlive question...

A

Atmapuri

Hi!

I was looking at the details of how KeepAlive
works to handle my unmanaged code interop.
Several question came up. Assuming I have:

public Test2(Object a)
{

}

public Test()
{
a = new MyObject();

Test2(a);
}

Is the call to Test2 the same as the call to GC.KeepAlive?
Can GC collect the object while one of its methods is executing,
if the object is not referenced within that method and after?

If Inside Test2 I make a reference to "a", can GC collect
the "a" immadiately after the reference, or only after Test2 finishes?

Does the behaviour change if I write:

public Test()
{
Test2(new MyObject());
}

Thanks!
Atmapuri
 
P

Patrick Steele

Hi!

I was looking at the details of how KeepAlive
works to handle my unmanaged code interop.
Several question came up. Assuming I have:

public Test2(Object a)
{

}

public Test()
{
a = new MyObject();

Test2(a);
}

Is the call to Test2 the same as the call to GC.KeepAlive?

It might have the same effect. Don't know for sure.
Can GC collect the object while one of its methods is executing,
if the object is not referenced within that method and after?

Hmmmm... Perhaps. Maybe the JIT compiler will optimize out the passing
of the parameter since it's never used. In that case, I would think
"a" could go away anytime after the "a = new MyObject" line. But this
is theoretical -- I don't know for sure.
If Inside Test2 I make a reference to "a", can GC collect
the "a" immadiately after the reference, or only after Test2 finishes?

At a minimum, it couldn't collect it until Test2 is done with it -- that
may be when Test2 finishes, or not.
 
B

Brian Gideon

Hi!

I was looking at the details of how KeepAlive
works to handle my unmanaged code interop.
Several question came up. Assuming I have:

public Test2(Object a)
{

}

public Test()
{
a = new MyObject();

Test2(a);

}

Is the call to Test2 the same as the call to GC.KeepAlive?

A call to any method usually behaves the same way as GC.KeepAlive.
But, in this particular case the JIT compiler could inline Test2,
determine that it has no side-effects on 'a', and make the new
MyObject eligible for collection even before 'a' is assigned.
Can GC collect the object while one of its methods is executing,
if the object is not referenced within that method and after?

Yes. An object can be collected while one of it's methods is
executing. It may seem counter intuitive, but it's perfectly safe
(assuming all code is managed of course) if the method doesn't
reference its owner (eg. extracting an instance variable from the
'this' pointer).
If Inside Test2 I make a reference to "a", can GC collect
the "a" immadiately after the reference, or only after Test2 finishes?

I don't know if the GC makes a distinction between method parameters
and other variables on the stack. But, I suspect it would be eligible
after it's last use like other local variables.
Does the behaviour change if I write:

public Test()
{
Test2(new MyObject());

}

I don't think the behavior would be any different from your first
example.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top