What has managed code achieved?

  • Thread starter Thread starter John
  • Start date Start date
Cor Ligthert said:
An object is only removed by the Garbage Collector, when it has itself no
reference anymore (that can simple be because it goes out of scope) and
which everybody forgets, no other object are pointing anymore to it (to
use another word).

That's not what I said.

Consider the objects A, B, and C, and -> denoting a reference:

A -> B -> C

If A can be reached from the "running code", B and C cannot be finalized.

However, when removing the reference from A to B

A B -> C

and neither B nor C can be reached from the "running code", both objects can
be destroyed by the GC although there is a reference from B to C. This even
works if there are circular references between these objects.
 
Ben Voigt said:
Blue screens result from kernel-mode bugs. Always. .NET doesn't change
anything in kernel mode.


There was a smiley, but my statement still holds. He asked for advantages of
CLR. As you have stated, I cannot get that deep in the CLR, so no blue
screens. ;-)

--
Gregory A. Beamer
MVP, MCP: +I, SE, SD, DBA

Subscribe to my blog
http://feeds.feedburner.com/GregoryBeamer#

or just read it:
http://feeds.feedburner.com/GregoryBeamer

********************************************
| Think outside the box! |
********************************************
 
Herfried,

It is friday evening, and you know as one of the few exactly what that means
for me, I give you an answer in the weekend.

:-)

Cor
 
The progress is going slow, but the direction is
unmistakable. I think the main holdup on Vista
was the problem that .Net is simply far too bloated:

Something being "far too bloated" has never been a deal-breaker for
Microsoft before, and I doubt it ever will be. One could argue that Windows
and its various subsystems is far too bloated as it stands. Making .NET an
embedded component of the OS and using managed libraries as the only API
method would hardly change that.
I don't think it's a matter of shoving it down anyone's
throat. It's a gradual transition, based on the idea that
selling software has seen its heyday and that services
are the way of the future. (Or at least it's the only idea
anyone has right now for keeping profits up.)

What you're talking about isn't related to embedding the framework into
Windows and using that as the primary API method, you're talking about
software as a service - an idea which MS has been touting and selling (to
varying degrees of success) even before .NET was around.

MS doesn't need to shove anything down anyone's throat.
They can just gradually make it more and more awkward for
"unmanaged" code to run, while simultaneously increasing the
limits on what unmanaged code is capable of doing, and at
the same time expanding their online offerings.

Then they gradually transited in completely the wrong direction with Vista,
didn't they? Aero is completely unmanaged. Why wasn't that .NET based,
seeing as how it was a totally new component of the OS?

I think MS realise that the CLR still hasn't reached the state it needs to
be in to be such an integral part of the OS itself. In future we might see
a change, but I don't see that harming anyone. I don't see it as MS
enforcing their will onto users either. So long as performance doesn't
suffer and we don't lose anything, I'd happily see unmanaged APIs and
(particularly) COM get flushed down the drain in favour of something more
secure, more easily governed, and a whole lot less archaic.

As it stands, I think they'll have to work very hard to kill off unmanaged
code and the C++ gurus that swear by it - after all, they employ a large
number of them. There are also a lot of things that managed code simply
cannot and will never be able to do, namely low level operations. I'd much
rather see a clear distinction where all high level APIs are managed and low
level hardware access is kept unmanaged and raw for performance reasons.
 
Hi Ben,

Just to clarify, are you saying that in VB6 if you didn't de-reference an
object before it went out of scope, it would automatically be cleaned up
anyway? I'm not saying this in an accusatory manner, but everything I ever
read in terms of good practice and even articles on MSDN seemed to imply
otherwise - in fact I can even remember it being touted as a selling point
to upgrade to VB.NET.

Example (VB6):

Private Sub Test()

Dim objRef As SomeClass
Set objRef = New SomeClass
' ...
' ...
Set objRef = Nothing ' <--- Dereferencing before it goes out of scope

End Sub

Are you saying that the last line, "Set objRef = Nothing", was therefore
unneccesary in VB6? I was always under the impression that memory leaks
courtesy of objects that are still referenced (but out of scope) would occur
if you did *not* de-reference before they went out of scope. I could've
sworn there was even a Dr GUI article where he discussed using specific Co*
API calls to increment/decrement references to objects in order to hack up a
weak reference system in VB6, saying something like "the object reference
therefore still exists even when [not if] you Set objRef = Nothing at the
end of the Sub". The implied logic (at least my interpretation) was that
every VB6 coder should Set objRef = Nothing before said reference falls out
of scope.

If this is not the case, then apparently VB6 was a bit smarter than I gave
it credit for!
 
Just to clarify, are you saying that in VB6 if you didn't de-reference an
object before it went out of scope, it would automatically be cleaned up
anyway? I'm not saying this in an accusatory manner, but everything I ever
read in terms of good practice and even articles on MSDN seemed to imply
otherwise - in fact I can even remember it being touted as a selling point
to upgrade to VB.NET.

Example (VB6):

Private Sub Test()

Dim objRef As SomeClass
Set objRef = New SomeClass
' ...
' ...
Set objRef = Nothing ' <--- Dereferencing before it goes out of scope

End Sub

Are you saying that the last line, "Set objRef = Nothing", was therefore
unneccesary in VB6?

I think that this is what Ben is saying, and I can confirm that it is
absolutely true. The above "Set objRef = Nothing" is like setting a
string to vbNullString before leaving a sub/function ... it frees
memory but that would happen automatically anyway.

Apart from API calls handled improperly, the only way to produce those
memory leaks that VB is allegedly well known for is to have unresolved
circular object references.
[...] then apparently VB6 was a bit smarter than I gave it credit for!

Hehe! :-)

Wolfgang
 
Well I'll be absolutely darned! I've heard people absolutely slate classic
VB for the requirement of having to de-ref objects before they fall out of
scope, and all this time poor old VB wasn't even guilty of it.

I still have a handful (albeit a shrinking handful) of legacy VB6 apps that
I have to maintain, so this information is still useful and relevant to me.

So thanks for that bit of information, Tom!



Tom Shelton said:
Hi Ben,

Just to clarify, are you saying that in VB6 if you didn't de-reference an
object before it went out of scope, it would automatically be cleaned up
anyway? I'm not saying this in an accusatory manner, but everything I
ever
read in terms of good practice and even articles on MSDN seemed to imply
otherwise - in fact I can even remember it being touted as a selling
point
to upgrade to VB.NET.

Example (VB6):

Private Sub Test()

Dim objRef As SomeClass
Set objRef = New SomeClass
' ...
' ...
Set objRef = Nothing ' <--- Dereferencing before it goes out of scope

End Sub

Are you saying that the last line, "Set objRef = Nothing", was therefore
unneccesary in VB6?

Yes. It was and is completely unnecessary. Simple to prove to your
self -
just create a VB6 class and put some output in the class terminate event.
I was always under the impression that memory leaks
courtesy of objects that are still referenced (but out of scope) would
occur
if you did *not* de-reference before they went out of scope.

You had the wrong impression.
I could've
sworn there was even a Dr GUI article where he discussed using specific
Co*
API calls to increment/decrement references to objects in order to hack
up a
weak reference system in VB6, saying something like "the object reference
therefore still exists even when [not if] you Set objRef = Nothing at the
end of the Sub". The implied logic (at least my interpretation) was that
every VB6 coder should Set objRef = Nothing before said reference falls
out
of scope.

Most of these sort of hacks were created to deal with the issue of
circular
references. Circular references are a classic pain for ref counting
memory
managment.

Ref counting has the advantage of deterministic finalization - but GC has
better object allocation/deallocation performance and doesn't have issues
with
circular references. Of course, you also loose deterministic
finalization,
which means that you the developer have to be more aware of what unmanaged
resources you maybe holding on to...
If this is not the case, then apparently VB6 was a bit smarter than I
gave
it credit for!

You have been indoctrinated into the myth that memory managment in
VB.CLASSIC
is some how difficult. It isn't, except for a couple of cases - module
level
values and circular references - the programmer does NOT need to set an
object
to nothing. VB automatically calls release on objects as they fall out of
scope.

Again the quote from Bruce McKinney in "Hardcore Visual Basic" (one of my
all
time favorite VB books!):

<quote>
In real Visual Basic code, references are rarely destroyed
explicitly by setting an object variable to Nothing. Instead,
objects are created and destroyed automatically when you
pass objects to procedures, return them from functions, set or
get them with properties, or destroy other objects that hold
references to them.
</quote>
 
Alex Clark said:
Just to clarify, are you saying that in VB6 if you didn't de-reference an
object before it went out of scope, it would automatically be cleaned up
anyway? I'm not saying this in an accusatory manner, but everything I
ever read in terms of good practice and even articles on MSDN seemed to
imply otherwise - in fact I can even remember it being touted as a selling
point to upgrade to VB.NET.

Example (VB6):

Private Sub Test()

Dim objRef As SomeClass
Set objRef = New SomeClass
' ...
' ...
Set objRef = Nothing ' <--- Dereferencing before it goes out of scope

End Sub

Are you saying that the last line, "Set objRef = Nothing", was therefore
unneccesary in VB6? I was always under the impression that memory leaks
courtesy of objects that are still referenced (but out of scope) would
occur if you did *not* de-reference before they went out of scope

No, the reference stored in the local variable would have been removed
automatically. However, there were some pitfalls: Jumping out of a 'With'
block, for example, led to a reference which could not be removed but
prevented the object from being destroyed:

\\\
Private Declare Sub CopyMemory _
Lib "Kernel32.dll" _
Alias "RtlMoveMemory" _
( _
ByRef Destination As Any, _
ByRef Source As Any, _
ByVal Length As Long _
)

Private Sub Form_Click()
Dim f As Form1
Set f = New Form1
Call MsgBox(GetRefCount(f)) ' 1.

' Increments reference count.
With f

' Jumping out of the block does not decrement the
' reference count.
GoTo Label

' Decrements reference count.
End With
Label:
Call MsgBox(GetRefCount(f)) ' 2.
End Sub

Private Function GetRefCount(ByRef Object As IUnknown) As Long
Call CopyMemory(GetRefCount, ByVal ObjPtr(Object) + 4, 4)
GetRefCount = GetRefCount - 2
End Function
///
 
Ok, let me than complete what you did not say.

An object is removed as soon as it has no existing reference anymore itself,
or that its reference is used in another object (not being the object
itself).

It can have a reference in a Module or the Class is Shared (static in C#),
Global or in a method. His own reference will set to nothing: as method
goes out of scope, as its object class goes out of scope "me" ("this" in C#)
or as soon as the program stops; or as a reference is set to another object.

But that is not everything, it will not be removed as long as another
something is pointing to the object, while that object itself is not an
object in the list of that.

An Example.

Drag a datagridview on your form, it will be set in the global part of your
form
Create a datatable with a row and add that to your datatable row collection.
Set that datatable as the dataset of your grid

Now the datatable will not be removed as long as you don't set the
dataSource of the datagridview to nothing or to another datatable.

This is an example as we have often seen here, where people thought it went
wrong (a bug) because they did not understand this.

Cor
 
No, the reference stored in the local variable would have been removed
automatically. However, there were some pitfalls: Jumping out of a 'With'
block, for example, led to a reference which could not be removed but
prevented the object from being destroyed:

Good point, forgot to mention this.

Jumping out of a With block is generally dangerous as can be seen
here:

'***
Option Explicit

Private Type TestType
Value As Long
End Type

Sub main()
Dim tt() As TestType
Dim l As Long
ReDim tt(2)
l = 0
Do
With tt(l)
.Value = l
If .Value = 2 Then Exit Do 'jumps out of block
End With
l = l + 1
Loop
ReDim Preserve tt(1) '->fails with RTE 10, array is locked
End Sub
'***

However, you were talking about *some* pitfalls and jumping out of a
With block as an *example*. Which other situations that lead to
omitted dereferencing do you have in mind?

Wolfgang
 
Wolfgang Enzinger said:
However, you were talking about *some* pitfalls and jumping out of a
With block as an *example*. Which other situations that lead to
omitted dereferencing do you have in mind?

Well, I only had the particular scenario I showed in my post in my mind, but
I was thinking about different reasons for jumping out of a 'With' block.
 
I asked around and got this response:
Most "serious" apps that Microsoft ships (including the OS) has a mix of
both .NET managed code and COM/ASM code--some more than others. Some are
nearly all .NET while others are built to use COM and need to be implemented
with COM.

--
__________________________________________________________________________
William R. Vaughn
President and Founder Beta V Corporation
Author, Mentor, Dad, Grandpa
Microsoft MVP
(425) 556-9205 (Pacific time)
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
____________________________________________________________________________________________
 
Hi Bill,

I get the idea that you are answering a message from somebody in a newsgroup
which has removed some groups in the grouplist.

In the VB language group it shows up as an answer to Herfried, but it has in
my idea not anything to do with his message.

Cor

William Vaughn (MVP) said:
I asked around and got this response:
Most "serious" apps that Microsoft ships (including the OS) has a mix of
both .NET managed code and COM/ASM code--some more than others. Some are
nearly all .NET while others are built to use COM and need to be
implemented with COM.

--
__________________________________________________________________________
William R. Vaughn
President and Founder Beta V Corporation
Author, Mentor, Dad, Grandpa
Microsoft MVP
(425) 556-9205 (Pacific time)
Hitchhiker's Guide to Visual Studio and SQL Server (7th Edition)
____________________________________________________________________________________________
 
Back
Top