Деструктор для синглтона

Вопрос: Должен ли я написать деструктор для синглтона, который имеет область действия программы (оживает, когда программа запускается, и умирает, когда программа завершается)

Подробности:

я перед дилеммой

«Написать деструктор для одноэлементного класса или нет?»

1) Этот класс имеет область действия программы 2) Класс использует много памяти в куче, поэтому его освобождение займет время

Когда пользователь выходит из программы, ответ должен быть быстрым, так зачем тратить время на освобождение памяти, занятой этим синглтоном, так как память будет освобождена, когда программа завершится.


person Satbir    schedule 26.09.2009    source источник
comment
Что такое «быстрый» в «ответ должен быть быстрым»?   -  person David Rodríguez - dribeas    schedule 26.09.2009
comment
@dribeas: Может быть, быстрый ответ на вызов wait() в межпроцессном взаимодействии?   -  person P Shved    schedule 26.09.2009


Ответы (6)


Если освобождение памяти занимает много времени, то не делайте этого. Это может быть большой и трудоемкой проблемой, особенно если освобождение памяти приводит к многочисленным промахам кеша. ОС выполнит эту работу (конечно, если вы работаете в системах, которые действительно это делают).

Однако, если ваш деструктор выполняет финализацию некоторых ресурсов (например, разблокировку файла или части оборудования), а вы используете «получение ресурсов — это инициализация», вы должны убедиться, что вызываются правильные деструкторы (например, деструкторы статического объекты вызываются после возврата вашей функции main()). Это справедливо, если некоторые из объектов, выделенных внутри вашего синглтона, также блокируют ресурсы!

Поэтому в большинстве случаев лучше на самом деле написать деструктор для такого объекта и заставить его освобождать память необязательно.


SSS, задавший вопрос, решил вообще не писать деструктор. Однако я хотел бы еще немного поспорить, что это не лучшее решение.

Не освобождать память для статического объекта (назовем его «статическим») — очень тонкая оптимизация, которая противоречит здравому смыслу и тому, как люди обычно пишут программы. Ваш код, выделяющий память и просто не имеющий деструктора, выглядит странно. Сверстники будут думать, что класс написан плохо, будут искать в нем ошибки (пока они в другом классе).

Вместо этого вы должны соответствовать общим стандартам кодирования, которые диктуют, что управление памятью в C++ должно быть правильным. Напишите деструктор и только после того, как он покажет, что у него есть значительное преимущество, чтобы не освобождать его, оберните код, чтобы он не вызывался.

Намерение не освобождать память должно быть явным.

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

или даже

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

но деструктор лучше сохранить.

person P Shved    schedule 26.09.2009
comment
вы правы: а) деструктору требуется много времени, чтобы удалить всю иерархию б) он однопоточный и не несет никакой ответственности за завершение любого ресурса, поэтому я решил не писать никакого деструктора, для лучшего использования опыта при закрытии приложения - person Satbir; 26.09.2009
comment
:) Уважаемый Павел, я уважаю ваши мысли, я согласен, что это будет выглядеть странно. Я уже следую идее о том, что намерение не освобождать память должно быть явным. Также я получу предупреждение об утечке памяти. Но я вижу увеличение ~ 300 миллисекунд на моем процессоре 2GhZ, оно будет меньше на основной машине с процессором Xenon. - person Satbir; 26.09.2009

Похоже, вы создаете Объект Бога, поэтому может быть полезно пересмотреть дизайн твой класс.

Добавляете ли вы деструктор или нет, зависит от того, стоит ли снижать производительность для освобождения и, в конечном итоге, перераспределения памяти.

person Justin Rusbatch    schedule 26.09.2009
comment
Если SSS верит в Бога, то почему бы и нет? ;-) - person P Shved; 26.09.2009
comment
Я, конечно, не утверждаю, что это не сработает — просто пытаюсь избавить его или тех, кто будет поддерживать приложение, от головной боли в будущем. - person Justin Rusbatch; 26.09.2009

Язык C++ не гарантирует, что память будет высвобождена при завершении программы, но любая малоприличная ОС сделает это без проблем.

Так что да, если

  • вы работаете на полуприличной ОС, и
  • деструктор ничего не должен делать, кроме освобождения памяти

тогда да, вы можете опустить деструктор, слить память и положиться на то, что ОС очистит вас.

Очевидным недостатком этого является то, что различные инструменты отладки могут кричать и кричать об утечках памяти.

Конечно, более фундаментальный вопрос: почему вы создаете синглтон, который выделяет так много памяти?

Это звучит как ужасный дизайн для меня.

person jalf    schedule 26.09.2009
comment
я согласен, что это ужасный дизайн, но система очень стабильна .. я не получу разрешение на изменение дизайна :) .. - person Satbir; 26.09.2009

Реализуйте деструктор, так как это правильный способ, и это будет наиболее удобная версия. Затем измерьте (создайте исполняемый файл, который просто создает синглтон и завершает работу) реальное время, необходимое для освобождения памяти.

После того, как вы получите неопровержимые факты о том, сколько стоит правильное удаление, не пишите неверный код. Если это занимает какое-то измеримое время, рассматривайте его как относительную меру по отношению к времени, в течение которого программа будет работать. В большинстве случаев обработка, необходимая приложению, будет намного больше, чем время, необходимое для освобождения памяти.

Если вы все еще считаете, что это занимает слишком много времени, подумайте, что обычный пользователь будет считать слишком большим, сколько раз пользователь открывает и закрывает приложение, действительно ли это что-то значит или нет.

Если в конце концов вы решите, что это слишком много, вы рискуете тем, что через некоторое время приложение будет изменено, синглтон может получить внешние ресурсы, а не освободить их - это особенно плохо с блокировками файлов...

Те, кто жертвует правильностью ради производительности, не заслуживают ни того, ни другого

person David Rodríguez - dribeas    schedule 26.09.2009

Если вы работаете под ОС Windows, вся память/ресурсы, занятые любым процессом, будут восстановлены при закрытии приложения, поэтому ИМХО это не имеет значения.

person Ahmed Said    schedule 26.09.2009
comment
Технически все операционные системы должны, но я хотел бы отметить, что Windows — это самый глючный менеджер памяти, который я видел в использовании в течение длительного времени. Я видел, как он терпит неудачу в таких задачах, хотя в более новых версиях Windows все не так плохо. - person ewanm89; 26.09.2009
comment
Возможно, вы могли бы подтвердить это утверждение каким-нибудь фактом? Приведите пример ситуации, когда Windows (Любая версия от 2000 и выше) не может восстановить память. В противном случае вы просто распространяете собственное невежество. - person jalf; 26.09.2009

Как было сказано, операционная система в любом случае должна освобождать память, однако вы действительно хотите доверять ей управление ею? По крайней мере, при явном уничтожении у глючного/плохо спроектированного диспетчера памяти больше шансов сделать это правильно.

Тогда у него будет два шанса сделать это правильно.

person ewanm89    schedule 26.09.2009
comment
Предполагая, что ваша ОС поддерживает это, вы можете полностью положиться на диспетчер памяти ОС, чтобы полностью уничтожить виртуальное адресное пространство процесса. Это происходит на другом концептуальном уровне, чем освобождение свободного хранилища C++. - person TheFogger; 26.09.2009
comment
Я видел несколько примеров, когда подобные менеджеры памяти не справились с такой задачей. Это зависит от разных факторов, теоретически да, должно работать. Помните, что диспетчер памяти ядра беспокоится о том, является ли эта память общей для нескольких процессов и тому подобное. В некоторых случаях ошибка может привести к неправильному обращению с памятью. - person ewanm89; 26.09.2009
comment
Я говорю, что если кто-то все равно управляет памятью, он меньше зависит от чего-то, что потенциально может быть сломанным ядром. - person ewanm89; 26.09.2009
comment
Если ваше ядро ​​сломано, утечка в вашем собственном процессе будет наименьшим поводом для беспокойства как для вас, так и для вашего клиента. Выберите другую платформу или приготовьтесь к тому, что ваша жизнь превратится в ад. - person Integer Poet; 14.08.2010