473,466 Members | 1,290 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Static constructors/destructors

I know how to create and use static constructors, but is there a such thing
as a static destructor?

If not, then how do you deallocate memory intialized in the static
constructor?

Thanks in advance,
Joe
Jan 25 '06 #1
12 2537
Static constructor is executed when a class is referenced for the first
time, any static data in a process will(/must) remain in memory until
the process is killed - static data in a running process can not be
destructed and it will always be destructed when the process exits.
Static constructor in .Net initializes static data, it is possible
because compiled assembly is just a stub of the executing native
assembly and the code is JIT compiled and filled in there.
Just try to match the situation with any language which compiles to
native assembly, static data must be initialized as soon as the assembly
is loaded in memory.

--
Abhijeet Dev

Joe Narissi wrote:
I know how to create and use static constructors, but is there a such thing
as a static destructor?

If not, then how do you deallocate memory intialized in the static
constructor?

Thanks in advance,
Joe

Jan 25 '06 #2
Abhijeet Dev wrote:
Static constructor is executed when a class is referenced for the first
time, any static data in a process will(/must) remain in memory until
the process is killed - static data in a running process can not be
destructed and it will always be destructed when the process exits.
Static constructor in .Net initializes static data, it is possible
because compiled assembly is just a stub of the executing native
assembly and the code is JIT compiled and filled in there.
Just try to match the situation with any language which compiles to
native assembly, static data must be initialized as soon as the assembly
is loaded in memory.


To add more clarity about some specific cases... the static constructor is
not constructing an object, but rather assigning values to static members
before they are used. Therefore, it doesn't quite make sense to match a
static constructor with a single destructor.

Those static members could be types that need destruction. Managed types
assigned to a static variable will rely on the finalizer to clean up
resources.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/

Jan 25 '06 #3
I have a c++.NET 2003 class library that has a class with the following basic
structure, with a static constructor that initializes unmanaged memory;
mainly char*s that I need to pass to unmanaged functions (c functions,
structures, etc) (where I have to __pin).

Arent the char*s below declared unmanaged and therefore need to be deleted?

public __gc class EAHConnection : public IEAHConnection
{

protected:
static String* m_defaultConnectionString;
static int m_defaultDnsTimeout;
static char* m_domainIsamPath;
static char* m_domainDatPath;

static EAHConnection()
{
m_defaultDnsTimeout = Int32::Parse(reader->Value);
m_defaultConnectionString = String::Copy(reader->Value);

m_domainIsamPath = (char*)(void*)Marshal::StringToHGlobalAnsi(
reader->Value);
m_domainDatPath = (char*)(void*)Marshal::StringToHGlobalAnsi(
reader->Value);
}

}
Dont I have to free those variables somewhere? Like...

Marshal::FreeHGlobal((int)m_domainIsamPath);
Marshal::FreeHGlobal((int)m_domainDatPath);
Thank you very much for effort and help.

Joe

"Brandon Bray [MSFT]" wrote:
Abhijeet Dev wrote:
Static constructor is executed when a class is referenced for the first
time, any static data in a process will(/must) remain in memory until
the process is killed - static data in a running process can not be
destructed and it will always be destructed when the process exits.
Static constructor in .Net initializes static data, it is possible
because compiled assembly is just a stub of the executing native
assembly and the code is JIT compiled and filled in there.
Just try to match the situation with any language which compiles to
native assembly, static data must be initialized as soon as the assembly
is loaded in memory.


To add more clarity about some specific cases... the static constructor is
not constructing an object, but rather assigning values to static members
before they are used. Therefore, it doesn't quite make sense to match a
static constructor with a single destructor.

Those static members could be types that need destruction. Managed types
assigned to a static variable will rely on the finalizer to clean up
resources.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/

Jan 26 '06 #4
Does that mean I have to implement the Finalize (or is it Dispose) method?

"Brandon Bray [MSFT]" wrote:
Abhijeet Dev wrote:
Static constructor is executed when a class is referenced for the first
time, any static data in a process will(/must) remain in memory until
the process is killed - static data in a running process can not be
destructed and it will always be destructed when the process exits.
Static constructor in .Net initializes static data, it is possible
because compiled assembly is just a stub of the executing native
assembly and the code is JIT compiled and filled in there.
Just try to match the situation with any language which compiles to
native assembly, static data must be initialized as soon as the assembly
is loaded in memory.


To add more clarity about some specific cases... the static constructor is
not constructing an object, but rather assigning values to static members
before they are used. Therefore, it doesn't quite make sense to match a
static constructor with a single destructor.

Those static members could be types that need destruction. Managed types
assigned to a static variable will rely on the finalizer to clean up
resources.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/

Jan 26 '06 #5
Any static field is deleted when the process exits or is killed. Static
fields go to the text segment of process memory rather than data
segment. Object instances (and member fields) go to the data segment and
anything in data segment must be freed as soon as process frees an
object pointer. You write destructor for things in data segment, never
for anything in text segment. Text segment includes
instructions,class-definition, static constants etc.
If a static field is subject to change, I am not sure, but the pointer
to it should be in text segment and the memory should be allocated on
stack/heap depending on it's type, even in that case the pointer can not
be dereferenced and so, the memory used by static fields will never be
deleted in process lifetime. You can check these facts better by using a
profiler.

--
Abhijeet Dev

Joe Narissi wrote:
I have a c++.NET 2003 class library that has a class with the following basic
structure, with a static constructor that initializes unmanaged memory;
mainly char*s that I need to pass to unmanaged functions (c functions,
structures, etc) (where I have to __pin).

Arent the char*s below declared unmanaged and therefore need to be deleted?

public __gc class EAHConnection : public IEAHConnection
{

protected:
static String* m_defaultConnectionString;
static int m_defaultDnsTimeout;
static char* m_domainIsamPath;
static char* m_domainDatPath;

static EAHConnection()
{
m_defaultDnsTimeout = Int32::Parse(reader->Value);
m_defaultConnectionString = String::Copy(reader->Value);

m_domainIsamPath = (char*)(void*)Marshal::StringToHGlobalAnsi(
reader->Value);
m_domainDatPath = (char*)(void*)Marshal::StringToHGlobalAnsi(
reader->Value);
}

}
Dont I have to free those variables somewhere? Like...

Marshal::FreeHGlobal((int)m_domainIsamPath);
Marshal::FreeHGlobal((int)m_domainDatPath);
Thank you very much for effort and help.

Joe

"Brandon Bray [MSFT]" wrote:
Abhijeet Dev wrote:
Static constructor is executed when a class is referenced for the first
time, any static data in a process will(/must) remain in memory until
the process is killed - static data in a running process can not be
destructed and it will always be destructed when the process exits.
Static constructor in .Net initializes static data, it is possible
because compiled assembly is just a stub of the executing native
assembly and the code is JIT compiled and filled in there.
Just try to match the situation with any language which compiles to
native assembly, static data must be initialized as soon as the assembly
is loaded in memory.

To add more clarity about some specific cases... the static constructor is
not constructing an object, but rather assigning values to static members
before they are used. Therefore, it doesn't quite make sense to match a
static constructor with a single destructor.

Those static members could be types that need destruction. Managed types
assigned to a static variable will rely on the finalizer to clean up
resources.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/

Jan 26 '06 #6
Joe Narissi wrote:
Dont I have to free those variables somewhere? Like...

Marshal::FreeHGlobal((int)m_domainIsamPath);
Marshal::FreeHGlobal((int)m_domainDatPath);


If the resources belong to the process (or the AppDomain as the case may
be), they could be freed by OS or the runtime. If the resource is not
managed by the runtime, and you want to release the resource when an
AppDomain shuts down, you can register a delegate with the
System::AppDomain::DomainUnload event.

That's only necessary if the static member doesn't have a finalizer (such as
a char*).

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Jan 27 '06 #7
Joe Narissi wrote:
Does that mean I have to implement the Finalize (or is it Dispose)
method?


If the resource the static member refers to is a ref class, that ref class
should implement a finalizer if it has resources to clean up.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Jan 27 '06 #8
Abhijeet Dev wrote:
Any static field is deleted when the process exits or is killed. Static
fields go to the text segment of process memory rather than data
segment. Object instances (and member fields) go to the data segment and
anything in data segment must be freed as soon as process frees an
object pointer. You write destructor for things in data segment, never
for anything in text segment. Text segment includes
instructions,class-definition, static constants etc.


While all of that is true for unmanaged code, it is different for managed
types. Static objects are allocated on the GC heap just like other dynamic
objects. That is true even if they are global static objects. The
C++-runtime library and the CRT coordinate to ensure the best semantics for
the memory management of these objects.

Static variables do need cleanup if they are managing a resource that
persists beyond the process lifetime (or the AppDomain lifetime). If the
variable is initialized at startup (as is the case with global variables),
the CRT registers the destructor for each object so they are cleaned up at
shut down. That is not the case for static constructors. If the static
constructor initializes a ref class, it is the finalizers responsibility to
clean up. If the static constructor initializes a value class, extra work
must be done to register clean up with the shut down event. Ideally, a ref
class would be used to abstract those resources.

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Jan 27 '06 #9
So Im a little confused... in my case, where the static constuctor sets a
char* via Marshal::StringToHGlobalAnsi, do I need to register a delegate with
the
System::AppDomain::DomainUnload event to clean up this resource?

Thanks for all your help!

Joe

"Brandon Bray [MSFT]" wrote:
Joe Narissi wrote:
Dont I have to free those variables somewhere? Like...

Marshal::FreeHGlobal((int)m_domainIsamPath);
Marshal::FreeHGlobal((int)m_domainDatPath);


If the resources belong to the process (or the AppDomain as the case may
be), they could be freed by OS or the runtime. If the resource is not
managed by the runtime, and you want to release the resource when an
AppDomain shuts down, you can register a delegate with the
System::AppDomain::DomainUnload event.

That's only necessary if the static member doesn't have a finalizer (such as
a char*).

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/

Jan 27 '06 #10
Joe Narissi wrote:
So Im a little confused... in my case, where the static constuctor sets
a char* via Marshal::StringToHGlobalAnsi, do I need to register a
delegate with the System::AppDomain::DomainUnload event to clean up
this resource?
Since the documentation topic doesn't say anything specific to AppDomains,
you would need to register your own cleanup code if you wanted to avoid
leaking resources when an AppDomain unloads. If you're not using AppDomains
(i.e. only concerned about process shutdown), you don't need to worry about
cleaning up memory since the OS will reclaim all the memory anyways.
Thanks for all your help!


No problem. :-)

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/

Jan 27 '06 #11
Thanks for the eye-opener.
This part of CLR memory management I can understand now, but it still
leaves few things popping-up in my mind :(

1. What kind of resources we must clean-up on AppDomain unload event. As
you mentioned in another message, clean-up of static variables with
managed type will rely on the finalizer(types'). So, static variables of
managed type we are not concerned about, assuming they are well-written.
If we have unmanaged memory e.g. char *(as you mentioned), when we try
to store something here, we request some memory from the OS memory
manager, it will be in use till the process is running, but when the
process exits, that part of memory is free. What a process is using is
Process Heap. As soon as the process is gone, the process heap is gone.
I understand that there must be some type of resources which may require
this clean-up process, but why memory? (or security implications?)

2. What I understand is, JIT compiler must be inserting code here and
there to allocate everything on the process heap and the process static
data is part of the stub every .Net assembly is bound to have and that
the details would be more clear by analyzing the ngen'ed image(trying,
but finding it close to impossible) rather than IL. AppDomain lifetime
is subset of the process lifetime, and if a resource remains referenced
by some part of the code in AppDomain lifetime, it still has to be freed
when the process lifetime is over?

4. How should we clean-up the resources accrued by static initialization
in a MarshalByRef singleton class, when used in an application with
multiple AppDomains?
(This is a bit too specific, but it seems to be the exception to this
idea, and what if it really comes up some day)

--
Abhijeet Dev

Brandon Bray [MSFT] wrote:
While all of that is true for unmanaged code, it is different for managed
types. Static objects are allocated on the GC heap just like other dynamic
objects. That is true even if they are global static objects. The
C++-runtime library and the CRT coordinate to ensure the best semantics for
the memory management of these objects.

Static variables do need cleanup if they are managing a resource that
persists beyond the process lifetime (or the AppDomain lifetime). If the
variable is initialized at startup (as is the case with global variables),
the CRT registers the destructor for each object so they are cleaned up at
shut down. That is not the case for static constructors. If the static
constructor initializes a ref class, it is the finalizers responsibility to
clean up. If the static constructor initializes a value class, extra work
must be done to register clean up with the shut down event. Ideally, a ref
class would be used to abstract those resources.

Jan 27 '06 #12
Hey Abhijeet... great questions!

Abhijeet Dev wrote:
1. What kind of resources we must clean-up on AppDomain unload event. As
you mentioned in another message, clean-up of static variables with
managed type will rely on the finalizer(types'). So, static variables of
managed type we are not concerned about, assuming they are well-written.
If we have unmanaged memory e.g. char *(as you mentioned), when we try
to store something here, we request some memory from the OS memory
manager, it will be in use till the process is running, but when the
process exits, that part of memory is free. What a process is using is
Process Heap. As soon as the process is gone, the process heap is gone.
I understand that there must be some type of resources which may require
this clean-up process, but why memory? (or security implications?)
If we're only concerned about cleaning up when the process finishes, then
there's no real concern about freeing memory. The OS will reclaim the memory
as you said.

When we're dealing with AppDomains, it's trickier. Because an AppDomain
creates a fake process within the OS's real process, the OS doesn't have the
ability to wipe clean all of the resources when a single AppDomain shuts
down and others continue to run. If a finalizer or some other cleanup
registered with the AppDomain unload event doesn't clean up the resources,
they will be tied up until the process ends. That means the other AppDomains
running inside the process will be starved for those resources.
2. What I understand is, JIT compiler must be inserting code here and
there to allocate everything on the process heap and the process static
data is part of the stub every .Net assembly is bound to have and that
the details would be more clear by analyzing the ngen'ed image(trying,
but finding it close to impossible) rather than IL. AppDomain lifetime
is subset of the process lifetime, and if a resource remains referenced
by some part of the code in AppDomain lifetime, it still has to be freed
when the process lifetime is over?
You're right that resources are freed when the process is over. That may or
may not coincide with the AppDomain shutdown. Analyzing code at compile time
isn't really possible. While the code might all be compiled, initialization
of static members of a class happens when that type is first used. (Note,
there are two modes for choosing when static data of a type is initialized,
but the type must be in use in both modes.) Since a type may only come in to
use on certain paths of execution, there's only a limited set of analysis
the JIT can do.
4. How should we clean-up the resources accrued by static initialization
in a MarshalByRef singleton class, when used in an application with
multiple AppDomains?
(This is a bit too specific, but it seems to be the exception to this
idea, and what if it really comes up some day)


Since Marshal By Ref objects cannot be a value type, you should be able to
write a finalizer. So, by making sure the finalizer works, there's no
concern with AppDomains.

If the finalizer cannot work, any static that creates the MBRO, would need
to register a clean up delegate with the AppDomain Unload event.

Hope that helps,

--
Brandon Bray, Visual C++ Compiler http://blogs.msdn.com/branbray/
Bugs? Suggestions? Feedback? http://msdn.microsoft.com/productfeedback/
Jan 31 '06 #13

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

Similar topics

467
by: mike420 | last post by:
THE GOOD: 1. pickle 2. simplicity and uniformity 3. big library (bigger would be even better) THE BAD:
3
by: Rajesh Garg | last post by:
Can we have private constructors and destructors? IF yes what is the use of such constructors or destructors.....in the sense where can these be implemented in a system................. I have...
11
by: Jonan | last post by:
Hello, For several reasons I want to replace the built-in memory management with some custom built. The mem management itlsef is not subject to my question - it's ok to the point that I have...
3
by: Amit | last post by:
is there anything like static constructors or destructors in C++ ? if yes, how to implement it? Thanks, Amit.
3
by: rahul8143 | last post by:
hello, I write a following program and have problem in understanding constructors and destructors. #include <iostream.h> class vector { public: double x; double y;
13
by: Adam H. Peterson | last post by:
I just made an observation and I wondered if it's generally known (or if I'm missing something). My observation is that static protected members are essentially useless, only a hint to the user. ...
5
by: ElanKathir | last post by:
Hi All ! I want to know about the constructors & Destructors, constructors ---> New Destructors --> What ? (Which keyword to use for Destructor) Thanks & Regards, ElanKathir.S.N, ASM...
4
by: hyd | last post by:
With C++/CLI - VS2005, is it possible to have static constructors that are automatically called when the owner assembly is loading ? Otherwise, how it is possible to call it without creating an...
20
by: JohnQ | last post by:
The way I understand the startup of a C++ program is: A.) The stuff that happens before the entry point. B.) The stuff that happens between the entry point and the calling of main(). C.)...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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
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
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
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...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
0
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...

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.