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

Добавьте библиотеку перед запуском скрипта. Вы можете добавить любой из следующих CDN , чтобы запустить ее.

Google:


Microsoft


Jquery

Если Вы хотите любую другую версию Jquery cdn, проверьте эту ссылку .

После этого:


Wordpress:


53
задан Unihedron 11 August 2014 в 02:43
поделиться

15 ответов

We overload the global new and delete operators where I work for many reasons:

  • pooling all small allocations -- decreases overhead, decreases fragmentation, can increase performance for small-alloc-heavy apps
  • framing allocations with a known lifetime -- ignore all the frees until the very end of this period, then free all of them together (admittedly we do this more with local operator overloads than global)
  • alignment adjustment -- to cacheline boundaries, etc
  • alloc fill -- helping to expose usage of uninitialized variables
  • free fill -- helping to expose usage of previously deleted memory
  • delayed free -- increasing the effectiveness of free fill, occasionally increasing performance
  • sentinels or fenceposts -- helping to expose buffer overruns, underruns, and the occasional wild pointer
  • redirecting allocations -- to account for NUMA, special memory areas, or even to keep separate systems separate in memory (for e.g. embedded scripting languages or DSLs)
  • garbage collection or cleanup -- again useful for those embedded scripting languages
  • heap verification -- you can walk through the heap data structure every N allocs/frees to make sure everything looks ok
  • accounting, including leak tracking and usage snapshots/statistics (stacks, allocation ages, etc)

The idea of new/delete accounting is really flexible and powerful: you can, for example, record the entire callstack for the active thread whenever an alloc occurs, and aggregate statistics about that. You could ship the stack info over the network if you don't have space to keep it locally for whatever reason. The types of info you can gather here are only limited by your imagination (and performance, of course).

We use global overloads because it's convenient to hang lots of common debugging functionality there, as well as make sweeping improvements across the entire app, based on the statistics we gather from those same overloads.

We still do use custom allocators for individual types too; in many cases the speedup or capabilities you can get by providing custom allocators for e.g. a single point-of-use of an STL data structure far exceeds the general speedup you can get from the global overloads.

Take a look at some of the allocators and debugging systems that are out there for C/C++ and you'll rapidly come up with these and other ideas:

(One old but seminal book is Writing Solid Code, which discusses many of the reasons you might want to provide custom allocators in C, most of which are still very relevant.)

Obviously if you can use any of these fine tools you will want to do so rather than rolling your own.

There are situations in which it is faster, easier, less of a business/legal hassle, nothing's available for your platform yet, or just more instructive: dig in and write a global overload.

76
ответ дан 7 November 2019 в 08:21
поделиться

Вам нужно перегрузить их, когда вызовы new и delete не работают в вашей среде.

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

3
ответ дан 7 November 2019 в 08:21
поделиться

Некоторые системы реального времени перегружают их, чтобы они не использовались после инициализации ..

6
ответ дан 7 November 2019 в 08:21
поделиться

UnrealEngine3 перегружает глобальные операции new и delete как часть своей системы управления основной памятью. Есть несколько распределителей, которые предоставляют разные функции (профилирование, производительность и т. Д.), И им нужны все распределения, чтобы пройти через это.

Редактировать: Для моего собственного кода я бы сделал это только в крайнем случае. Под этим я подразумеваю, что почти никогда не буду его использовать. Но мои личные проекты, очевидно, намного меньше / очень разные требования.

10
ответ дан 7 November 2019 в 08:21
поделиться

Самая распространенная причина перегрузки new и delete - это просто проверка на утечек памяти и статистика использования памяти. Обратите внимание, что «утечка памяти» обычно обобщается на ошибки памяти. Вы можете проверить такие вещи, как двойное удаление и переполнение буфера.

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

Все остальные случаи - это просто конкретные вещи, упомянутые в других ответах (запись на диск, использование ядра).

26
ответ дан 7 November 2019 в 08:21
поделиться

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

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

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

* к сожалению, дело не столько в реальной безопасности, сколько в ее внешнем виде ...

2
ответ дан 7 November 2019 в 08:21
поделиться

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

В Linux вы можете установить свою собственную версию malloc вместо системного, как в этом примере:

http://developers.sun.com/solaris/articles/lib_interposers.html

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

Поскольку вы делаете это в общей библиотеке с LD_PRELOAD, вам даже не нужно перекомпилировать приложение.

2
ответ дан 7 November 2019 в 08:21
поделиться

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

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

Когда срабатывает первая ошибка выделения памяти, у вас все еще есть время, чтобы предупредить пользователя об условиях нехватки памяти («Я смогу выжить еще немного, но вы можете сохранить свою работу и закрыть некоторые другие приложения »), сохранить свое состояние на диск, переключиться в режим выживания или что-то еще, что имеет смысл в вашем контексте.

2
ответ дан 7 November 2019 в 08:21
поделиться

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

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

0
ответ дан 7 November 2019 в 08:21
поделиться

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

Но в 99% случаев это делается как функция отладки для регистрации как часто, где, когда выделяется и освобождается память.

2
ответ дан 7 November 2019 в 08:21
поделиться

Перегрузка new & delete позволяет добавить тег к выделенным вам областям памяти. Я помечаю выделение для каждой системы, элемента управления или промежуточного программного обеспечения. Во время выполнения я могу видеть, сколько каждый использует. Может быть, я хочу увидеть использование синтаксического анализатора, отделенного от пользовательского интерфейса, или то, как много промежуточного программного обеспечения действительно использует!

Вы также можете использовать его для установки защитных полос вокруг выделенной памяти. Если / когда ваше приложение выйдет из строя, вы можете взглянуть на адрес. Если вы видите содержимое как «0xABCDABCD» (или что бы вы ни выбрали в качестве защиты), вы получаете доступ к памяти, которой не владеете.

Возможно, после вызова delete вы можете заполнить это пространство аналогичным узнаваемым шаблоном. Я считаю, что VisualStudio делает нечто подобное при отладке. Разве он не заполняет неинициализированную память 0xCDCDCDCD?

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

4
ответ дан 7 November 2019 в 08:21
поделиться

На самом деле игры довольно часто выделяют один огромный кусок памяти из системы, а затем предоставляют настраиваемые распределители с помощью перегруженных команд new и delete. Одна из важных причин заключается в том, что консоли имеют фиксированный размер памяти, что создает большие проблемы как для утечек, так и для фрагментации.

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

2
ответ дан 7 November 2019 в 08:21
поделиться

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

Например, у вас может быть серия пулов памяти с фиксированными размерами блоков. Переопределение глобального нового позволяет вам направить все 61-байтовые выделения, скажем, в пул с 64-байтовыми блоками, все 768-1024 байта выделены в пул блоков 1024b, все те, что выше этого, в 2048 пул блоков байтов и все, что больше 8 КБ, в общую рваную кучу.

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

Это часто делается в системах, которые критичны по времени и пространству, например в играх. 280Z28, Ми и Дэн Олсон объяснили почему.

15
ответ дан 7 November 2019 в 08:21
поделиться

Плагины Photoshop, написанные на C ++, должны переопределять оператор new , чтобы получать память через Photoshop.

2
ответ дан 7 November 2019 в 08:21
поделиться

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

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

0
ответ дан 7 November 2019 в 08:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: