Re: OOP

From: Michael D. Ober (obermd._at_.alum.mit.edu.nospam)
Date: 01/09/05


Date: Sat, 8 Jan 2005 23:16:44 -0700


"Ralph" <msnews.20.nt_consulting32@spamgourmet.com> wrote in message
news:OaE43Q08EHA.3376@TK2MSFTNGP12.phx.gbl...
>

Clipped for brevity

>
> You are correct. My comment is inaccurate and comes from the ancient myth
> that VB has some kind of "garbage collection", a la, .Net. It does not. VB
> is purely procedural in its handling of 'construction' and 'deletion' and
in
> most cases (such as auto variables) tracking the lifetime of an object in
VB
> is very straight-forward .
>
> The myth of a "garbage collector" has a basis in the 'side effects' you
> mentioned near the end of your comments. One can become confused by
mutliple
> references to the same object, COM, outProc services, and the interuption
of
> linear thought by event-handling. In these cases, objects can occasionally
> take on the characteristics of Lazarus or a Houdini, and appear rather
> mysterious. Thus the myth was born.
>
> In some ways the myth is useful. By considering the possibility of an
unseen
> "garbage collector", in league with Murphy, laying out there somewhere,
just
> waiting for an opportunity to pounce - one tends to manually set things to
> Nothing - ah, just in case. <g>
>
> -ralph
>
VB 6 does have a garbage collector. It's a reference counted GC that will
go through the heap and free memory from objects that have no references and
then compact the unused memory. To see it in action, create a collection
and then create a lot of large strings and add them to the collection. The
memory footprint of your application will increase. Then delete these
strings from the collection. The memory footprint will decrease. For
example, on my Windows 2000 Pro system:

Option Explicit
Option Compare Text

Sub Main()
  Dim c As New Collection
  Dim i As Long
  Dim d As Double

  d = 0
  For i = 1 To 40000
    c.Add String(i, "A")
    d = d + i
    Debug.Print c.Count & ": " & d
    DoEvents
  Next

  Do While c.Count > 0
    ' Integer division
    i = c.Count \ 2

    ' Force i to be at least 1
    If i < 1 Then i = 1

    ' Now deallocate
    d = d - Len(c(i))
    c.Remove i
    Debug.Print c.Count & ": " & d
    DoEvents
  Loop

  Debug.Print c.Count & ": " & d
End Sub

====================
Before the start of the program, Task Manager shows the following:

Mem Usage = 17,220K
VM Size = 7,700K

Putting a break point at the line "Do While c.Count > 0" reports

Mem Usage = 29,584K
VM Size = 1,591,884K

This shows that the memory was actually allocated and that Windows put most
of it in the swap file as it wasn't being referenced by the application.
Now put a break point on the final Debug.print line before the End Sub.

Mem Usage = 9,172K
VM Size = 11,760K

The difference in size from the start to the end is the overhead of
allocating the memory required to run the program itself.

If you run this program with the Windows Task Manager open to the Process
View, you will also see that the memory allocation increases are much faster
than the deallocation rate. This is because the allocation must take place
right now. Deallocation can take place after the fact, and it appears that
the combination of the VB 6 runtime and Windows 2000 VM subsystem does lag
slightly on deallocation. Also, the code above prevents the collection from
deallocating cleanly as it deallocates from the middle of the collection at
all times. Collections have been documented to be implemented as linked
lists, making middle deallocation the absolute worst at releasing memory.
However, the Task Manager still shows memory decreasing as the second loop
runs.

Compiling and running this program outside the IDE shows similar results.
The DoEvents are in the code to allow the runtime to perform memory
allocation and deallocation as needed.

Although relatively fast, reference counted memory management has a major
weakness. It can be fooled by creating two objects the reference each
other. Since neither object's reference count can go to zero without
special care. Here's an example of this type of behavior:

type A
   ptrB as B
   value as Variant
end type

type B
   ptrA as A
   value as Variant
end type

Sub Main()
  dim vA as A
  dim vB as B

  vA.ptrB = B
  vA.value = "Variable A contains a reference to B"

  vB.ptrA = A
  vB.value = "Variable B contains a reference to A"

' The problem at this point is that unless the programmer remembers to set
either vA.ptrB to Nothing or vB.ptrA to nothing, neither of these two
variables will ever have their reference count go to zero until the end of
the program, at which time Windows itself will reclaim the memory.

End Sub

The .NET GC is a true mark/compact garbage collector that starts with the
two known roots of memory allocation. These roots are the stack and also
"Global" variable list. It sweeps through memory and marks all objects that
are accessible from these two roots. Any object not accessible is then
reclaimed, followed by a compaction where all the free memory is moved to
the end of the heap. As a result, the variables vA and vB in the second
example wouldn't get marked as accessible when they go out of scope and the
GC could safely reclaim them.

Mike.



Relevant Pages

  • Re: GC performance - GC fragility
    ... I take care ). ... memory in an endless loop doesn't eat all the systems memory. ... reference an object that has been collected in the same way that you can ... otherwise allocation a single object would result in 100 ...
    (borland.public.delphi.non-technical)
  • Re: C++ Garbage Collector on VMS?
    ... case of a reference counting system, have a non-zero reference count) as ... to the beginning of the heap, updating the pointers to the objects as it ... (segregating allocation areas by type/size can help a lot there, ... any way with GC-controlled memory). ...
    (comp.os.vms)
  • Re: A re-announce on GCs defects
    ... It's bad for CPU/Resource intensive but memory cheap objects. ... reference counting can take up to 50% of your ... one strong references and you don't know when and where to call Dispose. ... Programmer doesn't have to worry about memory allocation. ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: what is the purpose of C++ smart pointer
    ... I know C++ has a concept that named smart pointer, ... You confuse reference counting with smart pointers. ... following the changes of the memory it points to. ... triggering deallocation of memory. ...
    (comp.os.linux.development.apps)
  • [RFC] page replacement requirements
    ... Submitting too much I/O at once can kill latency and even lead to deadlocks when bounce buffers are involved. ... Must be able to deal with multiple memory zones efficiently. ... When on completion of the write to their backing-store the reference bit is still unset a callback is invoked to place them so that they are immediate candidates for reclaim again. ... For traditional page replacement algorithms this is not a big issue since we just implement per zone page replacement; ...
    (Linux-Kernel)

Loading