Для чего может использоваться "new_handler" в C ++ помимо сборки мусора? - PullRequest
6 голосов
/ 05 апреля 2011

C ++ программы могут определять и устанавливать new_handler(), который должен вызываться из функций выделения памяти, например operator new(), если невозможно выделить запрошенную память.

Одно использование пользовательского new_handler() - работа с реализациями C ++, которые не выдают исключение при ошибке выделения .Другое использование - запуск сборки мусора в системах, которые реализуют сборку мусора.

Какие еще варианты использования пользовательского new_handler() существуют?

Ответы [ 3 ]

7 голосов
/ 05 апреля 2011

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

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

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

6 голосов
/ 05 апреля 2011

На большинстве серверов, над которыми я работал, new_handler освобождает предварительно выделенный блок (чтобы будущие новинки не сбоили) перед записью сообщения (регистратор использовал динамическую память) и прерыванием.Это гарантировало, что ошибка нехватки памяти была правильно зарегистрирована (вместо процесса просто "исчезающего", с сообщением об ошибке к cerr, который был подключен к /dev/null).

В приложениях, таких как редакторыи т. д. может быть возможно пролить части некоторых буферов на диск, а затем продолжить;если new_handler возвращается, оператор new должен повторить выделение, и если new_handler освободил достаточно памяти, выделение может произойти успешно (и если этого не произойдет, new_handler будет вызван снова, возможно, чтобы освободить еще больше).

1 голос
/ 05 апреля 2011

Я никогда не использовал его ни для чего - слишком много ОС предоставляют виртуальную память и SIGSEGV или аналогичные, если они не могут предоставить ее позже, поэтому не стоит делать систему, которая полагается на устойчивость к исчерпанию памяти: это часто вне рук C ++. Тем не менее, если вы разрабатывали систему, в которой можно / нужно полагаться, я легко могу представить ситуацию, когда некоторые данные в реальном времени передавались в очередь в вашем процессе, и вы обрабатывали их и записывали / отправляли результаты. так быстро, как вы могли (например, видео аппаратное потоковое видео для повторного сжатия на диск / сеть). Если бы вы добрались до стадии, когда вы больше не могли хранить, вам просто пришлось бы бросить немного, но как вы узнали бы, когда это стало так плохо? Установка произвольного ограничения была бы глупой, особенно если ваше программное обеспечение предназначено для встроенной среды / блока, который существует только для этой задачи. И, вероятно, вам не следует использовать такую ​​функцию случайно в системе с любым типом подкачки памяти на жестком диске, так как если вы уже находитесь в режиме подкачки, пропускная способность будет ниже. Но - после предостережений - может быть полезно отбросить пакеты на некоторое время, пока вы не наверстаете упущенное. Возможно, сброс каждого N-го кадра через буфер в очереди будет менее заметен, чем сброс фрагмента в конец или в начало очереди. Как бы то ни было, отбрасывание данных из очереди может быть нормальным использованием на уровне приложения (в отличие от подсистемы внутренней памяти) для чего-то вроде этого ...

...