tags:

views:

537

answers:

6

Question : Should i write destructor for a singleton which has program scope (comes alive when program starts and dies when program ends)

Detail :

i am in a dilemma on

"shall i write destructor for a singleton class or not ?"

1) This class has program scope 2) Class uses a lot of memory on heap, So releasing that will take time

When user is exiting program, Response should be fast , So why to spend time in freeing memory occupied by this singleton , As memory will be released as program will end.

A: 

If you are running under windows OS, all memory/resources occupied by any process will be reclaimed when application closes so IMHO it does not matter

Ahmed Said
Technically all OSes should, but I would point out windows is the most buggy memory manager I've seen in use for a long time. I've seen it fail at such tasks, although not so bad in newer windows versions.
ewanm89
Perhaps you could support that claim with some fact? Give an example of a situation where Windows (Any version from 2000 and up) fails to reclaim memory. Otherwise you're just spreading your own ignorance.
jalf
A: 

As pointed out the operating system should release memory on end anyway, however do you really want to trust it to manage it? At least with explicit destruction a buggy/badly designed memory manager has more chance to get it right.

It gets two chances to get it right then.

ewanm89
Assuming your OS supports it, you can absolutely rely on the OS memory manager to completely destroy a process' virtual address space. This happens at a different conceptual level than C++ freestore deallocation.
TheFogger
I've seen several examples when such memory managers have failed to perform such a task. It depends on various factors, theoretically yes it should work. Remember the kernel memory manager is worrying about whether it's shared memory bettween several processes and such too. A bug can cause them to mistreat memory in certain cases.
ewanm89
I'm saying if one is managing memory anyway, one is less reliant on something that could potentially be a broken kernel.
ewanm89
If your kernel is broken, leaks in your own process are the least of worries for both you and your customer. Choose another platform or prepare for your life to be hell.
Integer Poet
+2  A: 

It sounds like you're creating a God Object, so it might be beneficial reconsider the design of your class.

Whether or not you add a destructor depends on whether or not it's worth the performance hit to release, and eventually reallocate, the memory.

Justin R.
If SSS believes in God, why not? ;-)
Pavel Shved
I'm certainly not suggesting that it wouldn't work -- just trying to save him, or those who will be maintaining the app, some headaches in the future.
Justin R.
+3  A: 

If it takes a long time to release memory, then don't do it. This may be a big and time-consuming issue, especially if releasing memory leads to numerous cache misses. OS will do the job (of course, if you are operating on the systems that actually does that).

However, if your destructor does finalization of some resources (for example, unlocking a file or a piece of hardware), and you use "resource acquisition is initialization", you must ensure that the proper destructors are called (for example, those of static objects are called after your main() function returns). This holds if some of the objects allocated inside your singleton lock resources, too!

In most cases, therefore, it's better to actually write a destructor for such an object and make it release memory optionally.


SSS, who asked the question, decided not to write destructor at all. However, I'd like to argue a bit more that it's not the best solution.

Not freeing a memory for a static object (let's call it "static") is a very subtle optimization that contradicts common sense and how people usually write programs. Your code, allocating memory and merely having no destructor, looks weird. Peers will think that the class is badly written, will tend to look bugs in it (while they're in the other class).

Instead, you should conform to common coding standards which dictate that memory management in C++ should be correct. Do write a destructor and, only after it shows it has a significant boost not to deallocate, wrap the code for it not to be called.

Intent to not release the memory must be explicit.

MySingleton::~MySingleton()
{
#ifndef RELEASE
  // The memory will be released by OS when program terminates!
  delete ptr1;
  delete ptr2;
#endif
}

or even

MySingleton::~MySingleton()
{
  // We don't do anything here.
  // The memory will be released by OS when program terminates!
}

but destructor is better to persist.

Pavel Shved
you are right :a) Destructor takes a long time to delete all hierarchy b) Its a single threaded and do not hold any responsibility for finalzing any resource So i have decide not to write any destructor , For better use experience while shutting down application
sat
:) Dear Pavel , I respect your thoughts , i agree it will looks weird. I am already following idea of "Intent to not release the memory must be explicit"Also i will get waring for memory leaks.But i see a boost of ~300 milliseconds on my 2GhZ cpu, It will be less on main machine which has Xenon processor .
sat
+2  A: 

The C++ language does not guaranteee that memory will be reclaimed when the program terminates, but any half decent OS will do it without a problem.

So yes, if

  • you are running on a half decent OS, and
  • there is nothing else the destructor should do than release memory

then yeah, you can omit the destructor, leak the memory, and rely on the OS to clean up after you.

The obvious downside to this is that various debugging tools might scream and yell about memory leaks.

Of course, a slightly more fundamental question is why are you creating a singleton which allocates that much memory?

That sounds like terrible design to me.

jalf
i agree this is terrible design ,But system is very stable ..I wont get a permission to change design :) ..
sat
That's fair. :)
jalf
+2  A: 

Implement the destructor as it is the correct way and will be the most maintainable version. Then measure (create an executable that just creates the singleton and exits) the real time it takes to deallocate the memory.

After you have hard facts on what the cost of proper deletion is, don't write incorrect code. If it takes some measurable time, consider it as a relative measure with respect to the time the program will be running. In most cases the processing required for the application will be much more than the time it takes to free the memory.

If you still think it takes too much time, consider what a regular user will consider too much time, how many times the application is opened and closed by the user, if it really amounts to anything or not.

If at the end you decide it is too much, what you risk is that in some later time the application will be modified, the singleton could acquire external resources and not free them --this is specially bad with file locks...

Those who sacrifice correctness for performance deserve neither

David Rodríguez - dribeas