473,409 Members | 1,942 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,409 software developers and data experts.

Problem with C# not calling MC++ destrcutor

I have an application written in C# that uses objects written in a
managed C++ DLL. When I exit my app, my C# classes have their
destructors called, but the MC++ objects that those classes hold
references to do not get invoked (I can observe this from both
breakpoints in the code, and trace output to the console).

I was under the impression that when my C# object goes out of scope, it
would automatically dispose of all of the references it is holding. I'm
new to GC, so maybe it doesn't work this way? I know that during
application execution objects with a ref count of 0 might not be cleaned
up right away, but when my process exits, shouldn't I be able to rely on
all of my objects being garbage collected?

Thanks,
--Jeremy
Feb 2 '07 #1
7 1641
Jeremy Chaney wrote:
I have an application written in C# that uses objects written in a
managed C++ DLL. When I exit my app, my C# classes have their
destructors called, but the MC++ objects that those classes hold
references to do not get invoked (I can observe this from both
breakpoints in the code, and trace output to the console).

I was under the impression that when my C# object goes out of scope, it
would automatically dispose of all of the references it is holding. I'm
new to GC, so maybe it doesn't work this way? I know that during
application execution objects with a ref count of 0 might not be cleaned
up right away, but when my process exits, shouldn't I be able to rely on
all of my objects being garbage collected?

Thanks,
--Jeremy
Managed classes doesn't have destructors, as there are no reference
counters at all, so nothing happens when the last reference goes away.
They may have Finalizers, that is instead called when the objects are
going to be garbage collected. You should avoid having a Finalizer on a
class if you don't need one, as having a Finalizer means that the object
has to go through at least two garbage collection cycles before it's
released.

If you need to release unmanaged resources in your classes, you should
implement the IDisposable interface (which includes have a Finalizer as
backup). If you only have managed resources in your classes, there is
nothing that you need to release, and so you don't need any Finalizer.

When the application ends, it will try to call the Finalizer of all
objects that has one, but if this takes too much time, it will just kill
the objects anyway. This is another reason to avoid having a Finalizer
if you don't need one, so that the finalizing queue only contains
objects that really needs to be finalized.

--
Göran Andersson
_____
http://www.guffa.com
Feb 2 '07 #2
I guess you are technically correct about managed objects not having a
destructor, but they do support "~MyClass". In .NET-land should I be
referring to that as a Finalizer instead of a destructor?
As far as cleaning up resources, is it acceptable to put my clean up
code in "~MyClass" but also make use of manually calling
myClass.Dispose()? There are cases where I know that I don't need
certain objects anymore and it would be nice if I could put my cleanup
code in one place and know that it would be called regardless of what
caused the object to be destroyed.

I'm pretty surprised to hear that it is possible for my Finalizers to
not be called at shutdown. If I am being required to manually free up my
resources, what is the point of GC?

Thanks,
--Jeremy

Göran Andersson wrote:
Jeremy Chaney wrote:
>I have an application written in C# that uses objects written in a
managed C++ DLL. When I exit my app, my C# classes have their
destructors called, but the MC++ objects that those classes hold
references to do not get invoked (I can observe this from both
breakpoints in the code, and trace output to the console).

I was under the impression that when my C# object goes out of scope, it
would automatically dispose of all of the references it is holding. I'm
new to GC, so maybe it doesn't work this way? I know that during
application execution objects with a ref count of 0 might not be cleaned
up right away, but when my process exits, shouldn't I be able to rely on
all of my objects being garbage collected?

Thanks,
--Jeremy

Managed classes doesn't have destructors, as there are no reference
counters at all, so nothing happens when the last reference goes away.
They may have Finalizers, that is instead called when the objects are
going to be garbage collected. You should avoid having a Finalizer on a
class if you don't need one, as having a Finalizer means that the object
has to go through at least two garbage collection cycles before it's
released.

If you need to release unmanaged resources in your classes, you should
implement the IDisposable interface (which includes have a Finalizer as
backup). If you only have managed resources in your classes, there is
nothing that you need to release, and so you don't need any Finalizer.

When the application ends, it will try to call the Finalizer of all
objects that has one, but if this takes too much time, it will just kill
the objects anyway. This is another reason to avoid having a Finalizer
if you don't need one, so that the finalizing queue only contains
objects that really needs to be finalized.
Feb 2 '07 #3
I'm pretty surprised to hear that it is possible for my Finalizers to
not be called at shutdown. If I am being required to manually free up my
resources, what is the point of GC?
GC is here to clean up unreferenced _memory_. You should deal with other
(unmanaged) resources using the dispose pattern in C#. There has been a long
thread recently (named C++/CLI is the way to go) where a reference counted
model for disposing unused resources in C# has been proposed.

Can you show us your finalizers? My guess is you are trying to use them the
way they were not meant to be.
Feb 2 '07 #4
Lebesgue wrote:
>I'm pretty surprised to hear that it is possible for my Finalizers to
not be called at shutdown. If I am being required to manually free up my
resources, what is the point of GC?

GC is here to clean up unreferenced _memory_. You should deal with other
(unmanaged) resources using the dispose pattern in C#. There has been a long
thread recently (named C++/CLI is the way to go) where a reference counted
model for disposing unused resources in C# has been proposed.

Can you show us your finalizers? My guess is you are trying to use them the
way they were not meant to be.

I think I'm sinking in over my head here... :) When you say Finalizers,
do you mean my "~MyClass" method?

Here it is:

~MyCSharpClass()
{
foreach (KeyValuePair<Char, MyManagedCPPClasskvp in m_MyMap)
{
kvp.Value.Dispose();
}
m_myotherManagedCPPClass.Dispose();
}
The need for this destructor (I'm going to call it that until someone
tells me what to call it in C#) is surprising to me. The objects that I
have to call Dispose on are both Managed C++ objects. Shouldn't they
have their destructors called when "~MyCSharpClass" is called? . Before
I added the calls to Dispose, "~MyCSharpClass" was always called, but
the destructors for my Managed C++ objects were not. (I fixed this with
the addition of Dispose).

Thanks,
--Jeremy
Feb 2 '07 #5
Jeremy Chaney wrote:
I guess you are technically correct about managed objects not having a
destructor, but they do support "~MyClass". In .NET-land should I be
referring to that as a Finalizer instead of a destructor?
In my opinion, yes you should.

In the framework they are called finalizers, for example in the
SuppressFinalize method of the GC (garbage collector) class. They are
sometimes called destructors as they have the same syntax as C++
destructors, but I think that sticking to the name finalizers will cause
less confusion, as they work differently.
As far as cleaning up resources, is it acceptable to put my clean up
code in "~MyClass" but also make use of manually calling
myClass.Dispose()?
Actually, you should do it the other way around. In the proposed
implementation of the IDisposable interface, the finalizer is calling
Dispose(false);

The Dispose method should call the GC.SuppressFinalize method for the
object. This will remove the object from the finalizing queue,
effectively turning the object into a managed resource that safely can
be removed by the garbage collector.
There are cases where I know that I don't need
certain objects anymore and it would be nice if I could put my cleanup
code in one place and know that it would be called regardless of what
caused the object to be destroyed.
Implementing IDisposable with a finalizer as backup (which is the
proposed way to do it), will take care of that.

You should always try to call Dispose if you can, as that is a more
efficient way of freing up the resources.
I'm pretty surprised to hear that it is possible for my Finalizers to
not be called at shutdown. If I am being required to manually free up my
resources, what is the point of GC?
You should always try to free up all unmanaged resources as soon as
possible. That is usually before the application ends. Using finalizers
for freeing up unmanaged resources is just a backup. It's nice to have,
but you shouldn't rely on it completely.

--
Göran Andersson
_____
http://www.guffa.com
Feb 2 '07 #6
Jeremy Chaney wrote:
Lebesgue wrote:
>>I'm pretty surprised to hear that it is possible for my Finalizers to
not be called at shutdown. If I am being required to manually free up my
resources, what is the point of GC?
GC is here to clean up unreferenced _memory_. You should deal with other
(unmanaged) resources using the dispose pattern in C#. There has been a long
thread recently (named C++/CLI is the way to go) where a reference counted
model for disposing unused resources in C# has been proposed.

Can you show us your finalizers? My guess is you are trying to use them the
way they were not meant to be.

I think I'm sinking in over my head here... :) When you say Finalizers,
do you mean my "~MyClass" method?
Yes, he does.
Here it is:

~MyCSharpClass()
{
foreach (KeyValuePair<Char, MyManagedCPPClasskvp in m_MyMap)
{
kvp.Value.Dispose();
}
m_myotherManagedCPPClass.Dispose();
}
The need for this destructor (I'm going to call it that until someone
tells me what to call it in C#) is surprising to me. The objects that I
have to call Dispose on are both Managed C++ objects.
As you use objects that implement IDisposable, your class should also
implement IDisposable, so that the resurces can be freed safely and as
soon as possible.

If you are using the finalizer to free the resources, you have
absolutely no control over when it happens. If you implement
IDisposable, you can call the Dispose method when you want to free the
resources.
Shouldn't they
have their destructors called when "~MyCSharpClass" is called?
No. After your finalizer has run, there will be no references to the
child objects. At the next garbage collection they will be placed in the
queue of object to be finalized, and a background process will call
their finalizers eventually.

If you implement IDisposable (with Dispose containing the code that you
currently have in the finalizer), it will make the memory management
much more efficient. After you have called Dispose, there are no
finalizers to handle, and the garbage collector can free the memory of
your object and all it's child objects at the same time.
Before
I added the calls to Dispose, "~MyCSharpClass" was always called, but
the destructors for my Managed C++ objects were not. (I fixed this with
the addition of Dispose).

Thanks,
--Jeremy

--
Göran Andersson
_____
http://www.guffa.com
Feb 2 '07 #7
The need for this destructor (I'm going to call it that until someone
tells me what to call it in C#) is surprising to me.
Actually, there's no need for it in the form you have posted. See below how
to implement it "correctly".
Shouldn't they have their destructors called when "~MyCSharpClass" is
called?
No, finalizers (or call them destructors) don't call finalizers on instance
members automatically (I don't know if and under which circumstances they do
in C++, but I guess you think they do in C#). As Göran has stated in the
reply below, objects that have finalizers are placed in the finalization
queue and GC calls their finalizers on its finalizing thread when it finds
appropriate.

While Göran has explained the "theory" of what you should do, please let me
sum up how to implement what you have in practice.
Your finalizer code (the code you've posted) should go to the Dispose(bool
disposing) method you'll add to your class. You will also implement
IDisposable interface and from its Dispose() method, you'll call
Dispose(true) and also call GC.SuppressFinalize(this); - which will prevent
the object to be placed in the finalization queue =the finalizer will not
be called when the object is collected. Your finalizer would call the
Dispose(bool) method and you have done so already, that's why you are
calling SuppressFinalize().

Your finalizer should call Dispose(false) which will get rid of all
references to its instance members (set them to null) and rely on let their
finalizers to be called in the next collection (in case they have any and
they have not been Disposed yet). You should not rely on the finalizer to be
called - it's there just for the case you "forget" to call
IDisposable.Dispose() method on your object.

The whole point you are missing, I think, is that IDisposable.Dispose() is
meant to be called deterministically by you when you know you need to clean
up the resources used by the object.

"Jeremy Chaney" <j**@telestream.netwrote in message
news:e$**************@TK2MSFTNGP06.phx.gbl...
Lebesgue wrote:
>>I'm pretty surprised to hear that it is possible for my Finalizers to
not be called at shutdown. If I am being required to manually free up my
resources, what is the point of GC?

GC is here to clean up unreferenced _memory_. You should deal with other
(unmanaged) resources using the dispose pattern in C#. There has been a
long
thread recently (named C++/CLI is the way to go) where a reference
counted
model for disposing unused resources in C# has been proposed.

Can you show us your finalizers? My guess is you are trying to use them
the
way they were not meant to be.


I think I'm sinking in over my head here... :) When you say Finalizers,
do you mean my "~MyClass" method?

Here it is:

~MyCSharpClass()
{
foreach (KeyValuePair<Char, MyManagedCPPClasskvp in m_MyMap)
{
kvp.Value.Dispose();
}
m_myotherManagedCPPClass.Dispose();
}
The need for this destructor (I'm going to call it that until someone
tells me what to call it in C#) is surprising to me. The objects that I
have to call Dispose on are both Managed C++ objects. Shouldn't they
have their destructors called when "~MyCSharpClass" is called? . Before
I added the calls to Dispose, "~MyCSharpClass" was always called, but
the destructors for my Managed C++ objects were not. (I fixed this with
the addition of Dispose).

Thanks,
--Jeremy

Feb 2 '07 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: QINGFENG | last post by:
Hi, I am writing a Managed C++ wrapper DLL for some C functions in a statically linked library, such that I can use those C functions (through the C++.NET Wrapped mehtods) in a C# Windows User...
2
by: Edward Diener | last post by:
In C++ an overridden virtual function in a derived class must have the exact same signature of the function which is overridden in the base class, except for the return type which may return a...
1
by: DS | last post by:
I seem to have run into another strange anomaly with the monthCalendar control. I want to display 6 months at time with either the first half of the year (January-June) or the later half of the...
7
by: Fernando Barsoba | last post by:
Hi, After following the advice received in this list, I have isolated the memory leak problem I am having. I am also using MEMWATCH and I think it is working properly. The program does some...
1
by: MC-Advantica | last post by:
Does anyone have a simple "Hello World" like application that demonstrates unmanaged C++ calling managed C++ developed in VS2005? I'm confused by many posts as they discuss managed extensions from...
1
by: DJG79 | last post by:
Hi all, I am using an open source menu that i found and it works great, except for one thing that when the web page is not scrolled to the very top the drop down links will not stay visible. Has...
4
by: MC felon | last post by:
getline isn't working..... what's wrong with this code? #include <iostream> #include <string> #include <conio2.h// ignore this.. my old habits class base { int x,y;
6
by: per9000 | last post by:
An interesting/annoying problem. I created a small example to provoke an exception I keep getting. Basically I have a C-struct (Container) with a function-pointer in it. I perform repeated calls...
1
by: jsavagedesign | last post by:
This is a project I have been working on lately and I keep running into problems. The idea is to be able to attaching an animation to a movie clip and call it later. Or multiple animation at once. ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.