What has managed code achieved?

  • Thread starter Thread starter John
  • Start date Start date
In .NET, you are likely to adversely affect the performance of your
application by explicitly dereferencing your object (x = Nothing)! The GC
is optimized to look at running methods when collecting and to determine if
objects that still have application roots are actually going to be used in
the remainder of the method running. If you were to be cleaining up your
objects by setting them to Nothing, but hadn't reached that point of the
code yet, the GC would actually NOT mark your object that isn't going to be
used for any meaningful purpose for collection, now that you've got another
reference to it (the clean up code) later in the code.

I believe that was true at some point, and I guess it *might* still be
true for VB.NET, but it's not true for the C# 3.0 compiler and .NET
3.5. The compiler or JIT/GC - not sure which - understands that if the
only operation you're going to do on a variable is to write to it, it
doesn't count as a root.

Here's an example - compile with optimisation and without debug. (It
may work in other configurations, but that's what I've tried.)

using System;
using System.Threading;

public class GcTest
{
~GcTest()
{
Console.WriteLine("Finalized");
}

static void Main()
{
GcTest test = new GcTest();

Console.WriteLine("Before GC.Collect");

GC.Collect();
GC.WaitForPendingFinalizers();
// Make it clear this isn't a race condition for the console
Thread.Sleep(5000);
Console.WriteLine("Before test = null");

test = null;
Console.WriteLine("After test = null");
}
}

Output:
Before GC.Collect
Finalized
Before test = null
After test = null


I *totally* agree that it's a bad thing to do in terms of clarity, but
it doesn't have the performance effect you described.
 
Jon,

You know that you get a reaction from me on this message.
Did you have lessons from Cato the Elder?
snip
I believe that was true at some point, and I guess it *might* still be
true for VB.NET
end snip

You know better, before you answer that you wrote "might" I wrote about Cato
the Elder.

:-)

Cor
 
I only add too this, it does for me not matter what the price is in
hardware, it cost in OS administration to much.

I hope that I made it clear what I mean

And you know where I am stending in this.

Cor
 
Juan,

How many OS have you installed.

As I read what you write, then you have probably still MS-Dos 1.0 as well
installed?

Cor
 
Scott,

In this case I have respectfully to disagree with you and agree with Tom.

Mostly are the "Best practises" made in my idea by those who don't know much
about the problem and as something makes things working in one situation for
them, they use it in every situation.

(I did a litle investigation in this before you think I have simple read
this on Internet, that is why I answer now (noon here) and not yesterday
evening).

Cor
 
Well, there we have our disagreement. In fact, it was an onerous task in VB
6 to take care of object lifetime. That is a fact, not a myth. You may
have not had particular issues dealing with it, but the fact that VB 6 was
notorious for memory leaks and the fact that simply not setting an object
reference to Nothing was most likely the culprit tell us this. This is not
my opionion. VB 6 was well know for these issues.

Contrary to your assertion, simply letting a variable fall out of scope was
not the same thing as setting that variable reference to nothing before it
did. This makes all object variables vulnerable to memory leaks.

I don't expect that we'll wind up agreeing on this, but I'm pretty sure I
can find a couple of million VB 6 developers who will tell you that the need
to do object cleanup was not a "myth" in VB 6.

I can't resist from quoting that all because that's one unique
collection of nonsense.

Wolfgang (professional VB developer, version 3 - 6)
 
re:
!> How many OS have you installed.
!> As I read what you write, then you have probably still MS-Dos 1.0 as well installed?

Did you write web apps with MS-DOS 1.0 ?
Please explain the relevancy of your comments, in terms of what "dll hell" means.



Juan T. Llibre, asp.net MVP
asp.net faq : http://asp.net.do/faq/
foros de asp.net, en español : http://asp.net.do/foros/
======================================
 
re:
!> I can't resist from quoting that all because that's one unique collection of nonsense.

Can you explain why ?

Well, what can I say ... it's all plain wrong, simply.

It's not, and never was. As soon as the last object reference is
released, the object gets distroyed.

I honestly never heard about that in all those years.

If I don't need a particular object instance anymore then I'll set all
references to Nothing or let them run out of scope. If however I still
need it, then I don't. You can call that an "issue" or "memory leak".
I don't. I wonder how the system should know about my plans if I don't
state them?!

Strange that I never noticed any difference in all those years. In
fact, by checking whether the Terminate event is executed I can assure
that there *is no difference*.

I'm pretty sure it will be hard to find *one*, except Scott, of
course. *g*

Wolfgang
 
Less Blue Screens by junior developers. ;-)

Yeah, they are white nowadays, aren't they? ;-)
Realistically, from my COM days, the biggest real world advantage is not
having to register everything and the pain associated with registering
development builds to properly test.

Of course, if you use MTS, you had the option of dropping the running
process and droppping a new COM DLL over the old DLL. But this was thinking
WAY outside the box. You also ended up having to add the weight of MTS to
your app. Not too bad with web apps, which already had most of the weight.
Not as exciting for other apps.

With .NET, however, you can do this without a kludge. So that is a real
world advantage.

You can have the same with COM.

See: www.datenhaus.de/Downloads/DirectCOMDemo.zip

Wolfgang
 
It is about this text from you.
That's irrelevant.
The fact that several versions of the .Net Framework can coexist hardly
qualifies as "dll hell".

Like Bill wrote, it is not about two or more, it is about the situation.
Net Framework is a kind of OS layer. And therefore it in my eyes as
writting.

The fact that several versions of an OS can coexist .....................

Cor
 
¤ Respectfully, that sounds like your personal experience and an exception
¤ (pardon the pun) and not the rule. Just because you never had issues with
¤ this doesn't make it a non-issue or a myth.
¤
¤ If you've ever done much COM automation in VB 6, you know exactly how not
¤ setting object variables to Nothing is reality.

I know what you're saying but those type of issues were either due to poor coding practices or the
implementation of the COM libraries, especially out of process servers such as the Office
applications or in process libraries such as ADO. Those issues didn't really change in .NET, in fact
some of the problems were magnified.

¤ Setting object variables to Nothing in VB 6 was absolutely essential in
¤ order to ensure proper object clean up as well as decrementing the reference
¤ count.

It was a "good practice" but in my experience it wasn't absolutely essential all of the time.

¤
¤ The fact remains, sloppy coding or not, that managing memory in VB 6 was the
¤ responsibility of the developer and in .NET the CLR manages this for us to a
¤ much larger degree.

In most instances that's true. That is, unless COM is involved, then all bets are off.


Paul
~~~~
Microsoft MVP (Visual Basic)
 
Hi Juan,

¤ re:
¤ !> But have we traded one kind of DLL hell for another?
¤
¤ Not exactly.
¤
¤ Did you ever develop in Classic ASP ? "Dll Hell" was quite evident there.
¤
¤ 1. Different dll versions *prevented* your application from running in IIS.
¤ 2. Updating a dll meant manually stopping IIS, and all applications, so a single app could be updated

Of course with #2 you could actually kill the process that the web app was executing under (with
Process Explorer) without needing to stop IIS, although that method isn't very clean in a production
environment.

ASP always late bound to DLL libraries so it just used whatever was last registered. No binary
compatibility enforcement there.


Paul
~~~~
Microsoft MVP (Visual Basic)
 
Scott said:
I'm sorry, but that is absolutely wrong.

Hardly.

Let's see. If I have a reference to an object stored in a member variable
of a code module in VB6, the object won't be freed. In .NET.... Oh gee,
same thing (static member variable of a .NET class is same as member of a
VB6 code module).

If I have no references remaining in VB6, the reference count hits zero and
the object is freed. Deterministically. In .NET, same thing except the
object isn't freed until the GC runs, so there's an arbitrary delay
introduced.

There's a difference in the case of circular references, but the .NET
"solution" to the problem has plenty of drawbacks as well.
There is a difference between an object remaining in memory longer
than is absolutely necessary and an object remaining in memory for
the duration of the application's lifetime because it was never
explicitly de-referenced. In the former, memory may be taken up

In VB6 you don't need to explicitly dereference the variable, the compiler
generates Release calls automatically.
longer than is needed, but the object can still sit there causing no
harm, if it has been disposed (when needed), which .NET offers the
Using statement so that this can be done automatically. In the
latter, not only is memory taken up, but external resources are tied
up as well, because the class's terminate method is not called.

In .NET, you are likely to adversely affect the performance of your
application by explicitly dereferencing your object (x = Nothing)!

Unless it's a static variable, or a member variable of an object that lives
on, in which case it's necessary to remove the reference.
The GC is optimized to look at running methods when collecting and to
determine if objects that still have application roots are actually
going to be used in the remainder of the method running. If you were
to be cleaining up your objects by setting them to Nothing, but
hadn't reached that point of the code yet, the GC would actually NOT
mark your object that isn't going to be used for any meaningful
purpose for collection, now that you've got another reference to it
(the clean up code) later in the code.
In short, there is really no compelling reason to set object
variables to Nothing in .NET. The only thing you gain (and it's not

Yes there is, two of them actually -- instance members and static members.
 
re:
!> It is about this text from you.

I, still, don't see the relevance.

re:
!> Net Framework is a kind of OS layer.

Well, it *does* sit on top of the OS, like all programming frameworks do.

re:
!> The fact that several versions of an OS can coexist

The .Net framework is not an OS.




Juan T. Llibre, asp.net MVP
asp.net faq : http://asp.net.do/faq/
foros de asp.net, en español : http://asp.net.do/foros/
======================================
 
I don't expect that we'll wind up agreeing on this, but I'm pretty
sure I can find a couple of million VB 6 developers who will tell you
that the need to do object cleanup was not a "myth" in VB 6.

So? Some objects need cleanup, and that hasn't changed from VB6 to VB.NET.
I could find a couple million developers who write buggy software in VB.NET
(or C#, or any other language hosted on the CLR) because people like you
tell them they don't need to worry about object lifetimes, it's all taken
care of magically by .NET. When actually nothing could be further from the
truth. At best they let leave objects rooted and cause memory leaks which
are easy to track down in .NET (Ok, that's an advantage, .NET makes it
easier to find where you're leaking). At worst they let the finalizer clean
their objects, creating hard-to-debug race conditions.
 
re:
!> Of course with #2 you could actually kill the process that the web app
!> was executing under (with Process Explorer) without needing to stop IIS

The process that the web app was executing under *was* the IIS process.
The only way to update/change a dll in classic ASP was to kill the IIS process.

re:
!> although that method isn't very clean in a production environment

You can say that again.
In fact it didn't have a chance of working, never mind being "clean".





Juan T. Llibre, asp.net MVP
asp.net faq : http://asp.net.do/faq/
foros de asp.net, en español : http://asp.net.do/foros/
======================================
 
Contrary to your assertion, simply letting a variable fall out of
scope was not the same thing as setting that variable reference to
nothing before it did. This makes all object variables vulnerable to
memory leaks.

Don't know how I missed this fallacious claim.

Both of them do exactly the same thing, that is call Release on the object,
if any, previously referenced by the variable. Always. Even if you set the
variable to reference a different object instead of Nothing, the old one
gets its Release method called.
 
Paul said:
On Tue, 21 Oct 2008 07:36:44 -0400, "Juan T. Llibre"

Hi Juan,

¤ re:
¤ !> But have we traded one kind of DLL hell for another?
¤
¤ Not exactly.
¤
¤ Did you ever develop in Classic ASP ? "Dll Hell" was quite evident
there.
¤
¤ 1. Different dll versions *prevented* your application from running
in IIS.
¤ 2. Updating a dll meant manually stopping IIS, and all
applications, so a single app could be updated

Of course with #2 you could actually kill the process that the web
app was executing under (with Process Explorer) without needing to
stop IIS, although that method isn't very clean in a production
environment.

There was a convenient button for this in the IIS manager, to stop the
hosting process for just that app (if you selected isolated execution of
course).
 
Gregory said:
Less Blue Screens by junior developers. ;-)

Blue screens result from kernel-mode bugs. Always. .NET doesn't change
anything in kernel mode.
 
Back
Top