Garbage Colletor

  • Thread starter Johnny E. Jensen
  • Start date
J

Johnny E. Jensen

Hellow

I'am not sure what to think about the Garbage Collector.

I have a Class OutlookObject, It have two private variables.
Private Microsoft.Office.Interop.Outlook.Application _Application = null;
Private Microsoft.Office.Interop.Outlook.NameSpace _Namespace = null;

The Constructor:
public OutlookObject()
{
_Application = new Microsoft.Office.Interop.Outlook.Application();
_Namespace = _Application.GetNameSpace("MAPI");
}
..... after this alot of members and properties

When i need to do something in outlook, I'll instanciate the OutlookObject
objOL = new OutlookObject();
And when i don't need Outlook anymore I'll use objOL = null;

In my head this should destroy the objOL and thereafter also the
_Application and _Namespace in the Garbage Collector, but it don't happens
all time.
So I'll found a way that should force the destruction, the use of finalizer,
so i put this into the OutlookObject() class:

~OutlookObject()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

And I'll also tryed with the OutlookClass to dever from IDisposable class
and put in:
Public Dispose()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

With both the same result - Outlook don't get destroyed before i'll close
the application.

The problem is that I'll use Outlook a lot of times within my application,
and with the Task Manager I'll some time see five or more Outlook instances
WHY?????
And if there is so many Outlook instances, they stay open event after I'll
close my application. WHY???


Kind regards

Johnny E. Jensen
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Johnny said:
Hellow

I'am not sure what to think about the Garbage Collector.

That's just because you expect it to do something that it's not supposed
to do. ;)
I have a Class OutlookObject, It have two private variables.
Private Microsoft.Office.Interop.Outlook.Application _Application = null;
Private Microsoft.Office.Interop.Outlook.NameSpace _Namespace = null;

The Constructor:
public OutlookObject()
{
_Application = new Microsoft.Office.Interop.Outlook.Application();
_Namespace = _Application.GetNameSpace("MAPI");
}
.... after this alot of members and properties

When i need to do something in outlook, I'll instanciate the OutlookObject
objOL = new OutlookObject();
And when i don't need Outlook anymore I'll use objOL = null;

In my head this should destroy the objOL

It doesn't. It only makes the object available for garbage collection.

Garbage collections happen at times that the garbage collector decides,
and not every time an object is available for garbage collection. Also,
when a garbage collection happens, that doesn't guarante that all
available objects are collected. The garbage collector can decide that
it's not efficient to collect some of the objects at that time.
and thereafter also the
_Application and _Namespace in the Garbage Collector,

Actually, at the exact moment that the objOL can be garbage collected,
every object that it references (and isn't referenced somewhere else)
can also be garbage collected.
but it don't happens
all time.
So I'll found a way that should force the destruction, the use of finalizer,
so i put this into the OutlookObject() class:

~OutlookObject()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

A finalizer is not useful if you want to control when the objects are
released. An object that has a finalizer will be put in the freachable
queue instead of being collected. A background thread then runs the
finalizer methods in the objects one after one, but you have no control
over when this happens.

If it takes too long to go throught the freachable queue when the
application ends, the rest of the objects will just be discarded without
finalization, so it's not even guaranteed that the finalizer will ever run.
And I'll also tryed with the OutlookClass to dever from IDisposable class
and put in:
Public Dispose()
{
if ( _Application == null)

Why checking? Setting the reference to null again doesn't do any harm.

Why a return statement here? It's totally superflous as there is no more
code from this point to the end of the method.
else
{
_Application =null;
}
}

With both the same result - Outlook don't get destroyed before i'll close
the application.

Did you actually call the Dispose method? It's not called automatically.
 
P

Peter Duniho

Johnny said:
Hellow

I'am not sure what to think about the Garbage Collector.

You should love the GC. It's your friend.

If you don't love the GC, you probably just misunderstand it.

I don't know about the specific Outlook.Application object, but assuming
it has a Close() or Dispose() method, then you're not using it right.
If it doesn't have a Close() or Dispose() method, then your inability to
get it destroyed as you'd like is not the fault of the GC. It's the
fault of the Outlook.Application object.

As for your well-intentioned-but-not-quite-right attempts to get this to
work go...
[...]
When i need to do something in outlook, I'll instanciate the OutlookObject
objOL = new OutlookObject();
And when i don't need Outlook anymore I'll use objOL = null;

That is fine, as long as you don't need the Outlook.Application object
closed, freed, released, or otherwise discarded immediately. It sounds
as though you do though.
In my head this should destroy the objOL and thereafter also the
_Application and _Namespace in the Garbage Collector, but it don't happens
all time.

Nor should it. Setting the reference to null simply disconnects the
reference and makes it unreachable from your program's data. Nothing
will happen to it until the GC needs to actually release the memory
being used by the object, and that might not be in awhile.

Setting a reference to null is _only_ for causing that reference to be
eligible for garbage collection. It essentially frees the managed
memory used by the object, but the GC isn't necessarily going to bother
to try to take advantage of that until it needs to.

If you have other cleanup you need to do, you are required to do that
before you discard the reference. You would do this via some method the
object class provides, and that method is usually Close(), Dispose() or
both.
So I'll found a way that should force the destruction, the use of finalizer,
so i put this into the OutlookObject() class:

~OutlookObject()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

Your finalizer should call the Dipose() method, rather than doing
"dispose-like behavior" itself. Not that your finalizer actually
implemented "dispose-like behavior" (see below), but still.

And implementing a finalizer for a class that implements IDisposable is
a good idea, but the finalizer exists for redundancy. It should not be
considered the front line of defense, as it usually won't get called
right away, and might not ever be called.
And I'll also tryed with the OutlookClass to dever from IDisposable class
and put in:
Public Dispose()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

With both the same result - Outlook don't get destroyed before i'll close
the application.

No doubt. You didn't do anything that would cause the object to be
destroyed. All you did was release your reference to it, which as I
mentioned doesn't necessarily do anything right away.

If Outlook.Application implements IDisposable, then you'll want to call
that in your own Dispose() method. And you'll want your finalizer to
call Dispose().

If Outlook.Application has a Close() method, then you may also want to
implement a Close() method on your class that calls Close() on your
Outlook object.

If Outlook.Application has neither Dispose() nor Close(), nor any other
sort of "destroy this object" method, then you're out of luck. That's
something you'll need to take up with the Outlook folks. It's a bug for
them to implement a .NET class that has or represents unmanaged
resources (e.g. a process) but doesn't provide a method for explicitly
disposing those resources.

I suspect, however, that the Outlook.Application object does have a
Close() or Dispose() or similar, and if so then using that is the
solution to your problem.

Pete
 
G

Guest

You have to be really careful when working with COM Object Model .NET wrapper
classes for Office apps. For example the
Microsoft.Office.Interop.Outlook.Application class has a .Quit() method that
you should be calling to release the underlying COM coclasses when you are
done with it. Study the documentation carefully to ensure you are doing
everything right.
-- Peter
Recursion: see Recursion
site: http://www.eggheadcafe.com
unBlog: http://petesbloggerama.blogspot.com
BlogMetaFinder: http://www.blogmetafinder.com
 
C

Chris Mullins [MVP - C#]

Peter Duniho said:
You should love the GC. It's your friend.

I just signed up to do a session on the Garbage Collector at the Silicon
Valley code camp later this month.

So many people seem to have problems with it....
 
N

Nicholas Paldino [.NET/C# MVP]

This is in addition to the call to ReleaseComObject that should be made
on the reference after the Quit method is called. Also in addition to all
the references to all the objects that are exposed by the properties of the
application, should they be called.

This is one of those situations where if you are making a good number of
calls to an unmanaged COM object and it is spitting out tons of references,
you might want to do a GC when you know the work is done and you aren't
holding on to references to any COM object wrappers.
 
L

Larry Smith

Peter Duniho said:
I just signed up to do a session on the Garbage Collector at the Silicon
Valley code camp later this month.

So many people seem to have problems with it....

I can't help but laugh at the irony of this (not at you). Unmanaged
languages like C/C++ have been scoffed at for years because of memory
issues. Now people can't even handle a system that takes care of memory for
them. It goes a long way to demonstrate the complexities of our field
(there's no free lunch).
 
P

Peter Duniho

Larry said:
I can't help but laugh at the irony of this (not at you). Unmanaged
languages like C/C++ have been scoffed at for years because of memory
issues. Now people can't even handle a system that takes care of memory for
them. It goes a long way to demonstrate the complexities of our field
(there's no free lunch).

While there's probably some truth in your observation, I have to say
that my experience has been more the opposite. Languages or platforms
that manage memory with a garbage collector are often viewed as "lazy",
"inefficient", "toy-like", etc. with many people scoffing at them.
Those people assert that memory management is best done explicitly by
the program, even though it requires more code.

I have to admit that, while I don't think I was ever so rigid in my
thinking, even I held those beliefs to some degree. The memory
management of .NET was always a concern to me, until I actually started
using it.

But now, I love the garbage collector. :)

And yes, there's no such thing as a free lunch. However, there
definitely is a such thing as efficient engineering. The lunch isn't
technically "free", but it sure costs a lot less if you do things
efficiently. And I do feel that .NET as a platform offers great
opportunity for much-improved efficiency in the development process.
There are even at least a few examples of where using .NET results in an
_implementation_ that is more efficient than what most developers might
come up with.

That's about as close to getting a free lunch as you're likely to see. :)

Pete
 
C

Christof Nordiek

No doubt. You didn't do anything that would cause the object to be
destroyed. All you did was release your reference to it, which as I
mentioned doesn't necessarily do anything right away.

If Outlook.Application implements IDisposable, then you'll want to call
that in your own Dispose() method. And you'll want your finalizer to call
Dispose().

You should not call Dispose in the finalizer. When the finalizer runs, the
referenced object will also be eligible for collection resp. finalization,
and it's finalizer will run, maybe has allready run. But you should call
Dispose on the held objects in the Dispose method of the container.

Christof
 
W

Willy Denoyette [MVP]

This is also true for unmanaged clients using "automation" interfaces to
interact with Office Applications. A native COM client that fails to call
"Quit" (all office application support this method) will result in the
server (here Outlook.exe) to stay loaded in memory. As you correctly said,
learn the object model before you even start "automating" Office (or any
other DCOM server like) applications.

Willy.
 
J

Johnny E. Jensen

Hello

Thanks to all the replies.

Outlook don't have a Close() or Dispose(),but it has a Quit() method. But if
Outlook is running (the normal GUI Outlook) and if I use the Quit() method
this (GUI outlook) is closing - a bit anoing for the user.

As Nicholas mentioned to use the ReleaseComObject - this does the trick. So
my OutlookObject class has a Dispose() method and here I use the
ReleaseComObject(_Application) and ReleaseComObject(_Namespace) and it
works.

Kind regards

Johnny E. Jensen


Nicholas Paldino said:
This is in addition to the call to ReleaseComObject that should be made
on the reference after the Quit method is called. Also in addition to all
the references to all the objects that are exposed by the properties of
the application, should they be called.

This is one of those situations where if you are making a good number
of calls to an unmanaged COM object and it is spitting out tons of
references, you might want to do a GC when you know the work is done and
you aren't holding on to references to any COM object wrappers.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

"Peter Bromberg [C# MVP]" <[email protected]>
wrote in message
You have to be really careful when working with COM Object Model .NET
wrapper
classes for Office apps. For example the
Microsoft.Office.Interop.Outlook.Application class has a .Quit() method
that
you should be calling to release the underlying COM coclasses when you
are
done with it. Study the documentation carefully to ensure you are doing
everything right.
-- Peter
Recursion: see Recursion
site: http://www.eggheadcafe.com
unBlog: http://petesbloggerama.blogspot.com
BlogMetaFinder: http://www.blogmetafinder.com
 
W

Willy Denoyette [MVP]

Do you mean you are connecting to a running instance?
Note that even without this ReleaseComObject calls, there should be NO new
instance of Outlook getting created.
What kind of application is this (Windows, Console, other)?

Willy.



Johnny E. Jensen said:
Hello

Thanks to all the replies.

Outlook don't have a Close() or Dispose(),but it has a Quit() method. But
if Outlook is running (the normal GUI Outlook) and if I use the Quit()
method this (GUI outlook) is closing - a bit anoing for the user.

As Nicholas mentioned to use the ReleaseComObject - this does the trick.
So my OutlookObject class has a Dispose() method and here I use the
ReleaseComObject(_Application) and ReleaseComObject(_Namespace) and it
works.

Kind regards

Johnny E. Jensen


Nicholas Paldino said:
This is in addition to the call to ReleaseComObject that should be
made on the reference after the Quit method is called. Also in addition
to all the references to all the objects that are exposed by the
properties of the application, should they be called.

This is one of those situations where if you are making a good number
of calls to an unmanaged COM object and it is spitting out tons of
references, you might want to do a GC when you know the work is done and
you aren't holding on to references to any COM object wrappers.

--
- Nicholas Paldino [.NET/C# MVP]
- (e-mail address removed)

"Peter Bromberg [C# MVP]" <[email protected]>
wrote in message
You have to be really careful when working with COM Object Model .NET
wrapper
classes for Office apps. For example the
Microsoft.Office.Interop.Outlook.Application class has a .Quit() method
that
you should be calling to release the underlying COM coclasses when you
are
done with it. Study the documentation carefully to ensure you are doing
everything right.
-- Peter
Recursion: see Recursion
site: http://www.eggheadcafe.com
unBlog: http://petesbloggerama.blogspot.com
BlogMetaFinder: http://www.blogmetafinder.com



:

Hellow

I'am not sure what to think about the Garbage Collector.

I have a Class OutlookObject, It have two private variables.
Private Microsoft.Office.Interop.Outlook.Application _Application =
null;
Private Microsoft.Office.Interop.Outlook.NameSpace _Namespace = null;

The Constructor:
public OutlookObject()
{
_Application = new Microsoft.Office.Interop.Outlook.Application();
_Namespace = _Application.GetNameSpace("MAPI");
}
..... after this alot of members and properties

When i need to do something in outlook, I'll instanciate the
OutlookObject
objOL = new OutlookObject();
And when i don't need Outlook anymore I'll use objOL = null;

In my head this should destroy the objOL and thereafter also the
_Application and _Namespace in the Garbage Collector, but it don't
happens
all time.
So I'll found a way that should force the destruction, the use of
finalizer,
so i put this into the OutlookObject() class:

~OutlookObject()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

And I'll also tryed with the OutlookClass to dever from IDisposable
class
and put in:
Public Dispose()
{
if ( _Application == null)
return;
else
{
_Application =null;
}
}

With both the same result - Outlook don't get destroyed before i'll
close
the application.

The problem is that I'll use Outlook a lot of times within my
application,
and with the Task Manager I'll some time see five or more Outlook
instances
WHY?????
And if there is so many Outlook instances, they stay open event after
I'll
close my application. WHY???


Kind regards

Johnny E. Jensen
 
J

John Duval

<snip>








You should not call Dispose in the finalizer. When the finalizer runs, the
referenced object will also be eligible for collection resp. finalization,
and it's finalizer will run, maybe has allready run. But you should call
Dispose on the held objects in the Dispose method of the container.

Christof- Hide quoted text -

- Show quoted text -

Just a point of clarification for other people who might misread your
post -- calling Dispose from the finalizer is a common pattern and
it's perfectly ok to do. You just need to make sure that when you do
it, your Dispose method doesn't try to touch other managed objects
when called from the finalizer. As you point out, these other managed
objects might have already been cleaned up, so calling them will lead
to errors. The pattern I've seen most often is to have Dispose( ) and
the finalizer both call Dispose(bool disposing). When calling from
Dispose( ), pass disposing=true and call GC.SuppressFinalize(this).
When calling from the finalizer, disposing=false. Inside Dispose(bool
disposing), you should dispose other managed resources only if
disposing=true.

John
 
L

Larry Smith

I can't help but laugh at the irony of this (not at you). Unmanaged
While there's probably some truth in your observation, I have to say that
my experience has been more the opposite. Languages or platforms that
manage memory with a garbage collector are often viewed as "lazy",
"inefficient", "toy-like", etc. with many people scoffing at them. Those
people assert that memory management is best done explicitly by the
program, even though it requires more code.

This is simply human nature at work. People who master any complex skill
will generally feel superior to those who master a "lesser" skill (one
that's less complicated). They then convince themselves that the lesser
skill itself must also be inferior in some way. It's a fallacious argument
but most are guilty of it to some extent.
I have to admit that, while I don't think I was ever so rigid in my
thinking, even I held those beliefs to some degree. The memory management
of .NET was always a concern to me, until I actually started using it.

But now, I love the garbage collector. :)

And yes, there's no such thing as a free lunch. However, there definitely
is a such thing as efficient engineering. The lunch isn't technically
"free", but it sure costs a lot less if you do things efficiently. And I
do feel that .NET as a platform offers great opportunity for much-improved
efficiency in the development process. There are even at least a few
examples of where using .NET results in an _implementation_ that is more
efficient than what most developers might come up with.

That's about as close to getting a free lunch as you're likely to see. :)

As far as handling resources is concerned however, I think C++ has always
been unfairly maligned. Not only is it much less error-prone than people
believe (IMHO), the RAII paradigm itself is a cleaner design compared to a
GC system (again, IMHO). While it would be very difficult for anyone to
technically [dis]prove it (I certainly can't), I base it solely on my own
experience.
 
P

Peter Duniho

Larry said:
This is simply human nature at work. People who master any complex skill
will generally feel superior to those who master a "lesser" skill (one
that's less complicated). They then convince themselves that the lesser
skill itself must also be inferior in some way. It's a fallacious argument
but most are guilty of it to some extent.

I have the impression that you feel it's also a fallacious argument that
C/C++ is deserving of scorn and scoffing. Which is fine...I think
there's a lot of pointless scorning and scoffing going on in both
directions.

My point was simply that the scorn and scoffing isn't limited to the
C/C++ direction. It's also directed at garbage collection, and is just
as fallacious in that case as the case you mention.
As far as handling resources is concerned however, I think C++ has always
been unfairly maligned. Not only is it much less error-prone than people
believe (IMHO), the RAII paradigm itself is a cleaner design compared to a
GC system (again, IMHO). While it would be very difficult for anyone to
technically [dis]prove it (I certainly can't), I base it solely on my own
experience.

Well, my experience is the opposite. It is simply not possible to have
a memory leak in a garbage collection system. But memory leaks abound
in conventionally written C/C++ applications. I see it all the time.

There are ways to write code in a way that helps ensure against memory
leaks, but these aren't things that the language provide. They are
things that the developer must implement oneself (for example, code in
the debug build that actually tracks memory allocations and requires
idle-time consistency checks).

Now, does that mean that C++ is as error-prone as people believe? I
don't know. What do people believe? How do you measure that? But in
terms of C++ being more error-prone than a garbage collecting system
goes, I'd say that's easily observed and demonstrated.

IMHO the only real error likely to come up with respect to memory
management is, by definition, failing to manage memory correctly. That
is, either failing to allocate memory when you need it, or failing to
release it when you're done. The former is a trivial problem, easily
solved in any paradigm, while the latter simply doesn't exist in a
garbage collecting system.

So it's easily proven that, as long as one is looking only at those
kinds of errors, C/C++ is trivially more error-prone than a
garbage-collecting system.

Is the explicit allocation-and-release of C/C++ itself unwieldy and
excessively error-prone? No, I don't think so. I agree with you that
it's actually not hard to use, even while ensuring correct code. But it
is very unforgiving of carelessness, and unfortunately there are a lot
of programmers out there whose primary identifying characteristic is
carelessness.

I don't know how to evaluate "cleaner design" in this context. If
you're talking about the design of the memory manager, I'd have to agree
that a GC memory manager is more complicated, less "clean". On the
other hand, that only needs to be written once. I would definitely
disagree if you are trying to claim that the design of code written that
_uses_ the memory manager is "cleaner" in C/C++ than if using a GC
memory manager. What could be cleaner than not having to write the code
in the first place?

But really, the only thing I was pointing out is that just as you've
observed people scoffing at the C/C++ paradigm, I have observed people
scoffing at the garbage collection paradigm. It's not as one-sided as
your post seems to imply, and in fact (maybe as a result of the
environment in which I work) my experience has been that I see more
people criticizing the GC paradigm than the other way around.

Pete
 
P

Peter Duniho

Christof said:
You should not call Dispose in the finalizer. When the finalizer runs,
the referenced object will also be eligible for collection resp.
finalization, and it's finalizer will run, maybe has allready run. But
you should call Dispose on the held objects in the Dispose method of the
container.

As John says, that's not true. I may not have been clear enough in my
own post, but you should call your own Dispose() in the finalizer to
ensure that unmanaged resources in your own object are released.

But really, the situation here isn't about the finalizer at all. As I
said, that's a backup plan for when things aren't coded right.

The non-finalizing scenario (indicated by the boolean passed in) in the
Dispose() method of the class should release managed and unmanaged
resources, and should call the appropriate method on the
Outlook.Application object (that is apparently the Quit() method, as
Peter Bromberg has pointed out) to release that object.

And the OP's code should call his own class's Dispose() method directly,
rather than relying on the finalizer.

I don't know whether the Outlook.Application finalizer also calls
Quit(), but if it doesn't, that would mean it's essentially an unmanaged
resource and your own (that is, the OP's) Dispose() method should call
Quit() even in the finalizing case.

Pete
 
C

Chris Mullins [MVP - C#]

Peter Duniho said:
Well, my experience is the opposite. It is simply not possible to have a
memory leak in a garbage collection system. But memory leaks abound in
conventionally written C/C++ applications. I see it all the time.

Well, for what it's worth, in a 3 hour presentation on application Tuning,
about 1/2 that time is spent on Memory Leaks, and how to track them down.

Just like in C/C++ land, they're due to a user misunderstanding how GC works
and making a silly mistake. For some reason, the people who most often seem
to get bitten are novice devs who discover they really like static
variables...

.... so I spend quite a bit of time using a Memory Profiler, and showing them
how to read it's output.

My favorite leaks invoke making my laptop (with 2GB of memory) generate an
OOM while only actually allocating a few hundred KB of memory. (I have a
very nasty pinning / fragementation demo that really drives home the
issue...)
 
M

Martijn Mulder

Chris Mullins [MVP - C#] schreef:
Just like in C/C++ land, they're due to a user misunderstanding how GC works
and making a silly mistake. For some reason, the people who most often seem
to get bitten are novice devs who discover they really like static
variables...

Can you give us a small example when and how a static variable can cause
problems with the Garbage Collector?
 
L

Larry Smith

As far as handling resources is concerned however, I think C++ has always
been unfairly maligned. Not only is it much less error-prone than people
believe (IMHO), the RAII paradigm itself is a cleaner design compared to
a GC system (again, IMHO). While it would be very difficult for anyone to
technically [dis]prove it (I certainly can't), I base it solely on my own
experience.

Well, my experience is the opposite. It is simply not possible to have a
memory leak in a garbage collection system. But memory leaks abound in
conventionally written C/C++ applications. I see it all the time.

It's a religious issue and both have their pros and cons. While C++ may be
more error-prone than a GC system however (for releasing resources), there
need not be a significant difference. The problem is almost entirely a human
one. It's extremely easy to handle resources in C++ as you stated but the
language's reputation has often suffered because of its practioners (most
programmers being very poor at what they do). My own opinion however is that
in the hands of those who really know what they're doing (few and far
between), RAII is a cleaner approach than a GC system. By clean I mean it's
more natural to release your resources in a destructor than to wait for a GC
to run (not to be confused with easier or less error prone - it's clearly
not). The "using" statement for performing this in C# for instance (or even
worse, a "finally" block), is ugly compared to a C++ destructor. The
destructor is nicely symmetrical with its constructor. The latter
initializes the object and the former cleans it up. This occurs immediately
when an object goes out of scope so your resources only exist for as long as
they're needed. It's all very well controlled and understood. You know
exactly when clean up is going to occur and need not worry the timing of a
GC. In fact, a GC itself can even promote sloppy behaviour. People become
so used to it doing the clean up that they can neglect to explicitly clean
something up themselves when the situation calls for it (such as immediately
releasing a resource that might later cause something else to fail if it
hasn't been GC'd yet). Or people might always perform shallow copies of
their objects where a deep copy is required (since it's just so easy). In
C++ you have to think about these things more but that deeper thinking
process also sharpens your understanding of the issues IMO (and hopefully
the design of your app). Of course this is all a Utopian view of things. In
the real world most programmers require the handholding that a GC offers.
 
C

Chris Mullins [MVP - C#]

Can you give us a small example when and how a static variable can cause
problems with the Garbage Collector?

public class MyWebService
{
private static List<Byte[]> _myReceivedData;

private void DataFromAWebService(Byte[] rawData)
{
_myReceivedData.Add(rawData);
// Do operations
}
}

I see "innocent" code that looks like this all the time. The List, because
it's static, is never cleaned up.

People add data into it, and forget the list is static. They exepect that
when the class instance of MyWebService goes away, that the list of received
data will as well.

It's a really simple error, but I see it again and again and again...
 

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