Мы перегружаем глобальные операторы new и delete, в которых я работаю по многим причинам:
- объединение в пул все небольшие выделения - уменьшает накладные расходы, уменьшает фрагментацию, может повысить производительность для приложений с небольшим распределением ресурсов
- кадрирование выделений с известным временем жизни - игнорируйте все освобождения до самого конца этого периода, затем освободите их все вместе (по общему признанию, мы делаем это больше с перегрузками локальных операторов, чем с глобальными)
- выравнивание корректировка - по границам кэширования и т. Д.
- alloc fill - помогает разоблачить использование неинициализированных переменных
- free fill - помогает разоблачить использование ранее удаленной памяти
- без задержки - повышение эффективности свободного заполнения, иногда повышение производительности
- часовые или ограждения - помогают выявить переполнения буфера, опустошения и случайный дикий указатель
- перенаправление выделений - для учета NUMA, специальных областей памяти или даже для разделения отдельных систем в памяти (например, для встроенных языков сценариев или DSL)
- сборка мусора или очистка - снова полезно для этих встроенных языков сценариев
- проверка кучи - вы можете пройтись по структуре данных кучи каждый N выделяет / освобождает, чтобы убедиться, что все выглядит нормально
- учет , включая отслеживание утечек и снимки / статистика использования (стеки, возрасты распределения и т. Д.)
Идея нового / удаленного учета действительно гибкая и мощная: вы можете, например, записывать весь стек вызовов для активного потока всякий раз, когда происходит выделение ресурсов, и собирать статистику об этом. Вы можете отправить информацию о стеке по сети, если у вас нет места для ее локального хранения по какой-либо причине. Типы информации, которую вы можете собрать здесь, ограничены только вашим воображением (и, конечно, производительностью).
Мы используем глобальные перегрузки, потому что там удобно размещать множество общих функций отладки, а также вносить существенные улучшения во все приложение, основываясь на статистике, которую мы собираем по тем же перегрузкам.
Мы все еще используем собственные распределители для отдельных типов; во многих случаях ускорение или возможности, которые вы можете получить, предоставляя пользовательские распределители, например, единая точка использования структуры данных STL намного превышает общее ускорение, которое вы можете получить от глобальных перегрузок.
Взгляните на некоторые из распределителей и систем отладки, которые существуют для C / C ++, и вы быстро найдете эти и другие идеи:
(Одна старая, но оригинальная книга - Написание сплошного кода , в которой обсуждаются многие причины, по которым вы, возможно, захотите предоставить пользовательские распределители в C, большинство из которых по-прежнему очень актуальны.)
Очевидно, что если вы можете использовать любой из этих прекрасных инструментов, вы захотите сделать это, вместо того, чтобы использовать свой собственный.
Бывают ситуации, когда это быстрее, проще, меньше хлопот с бизнесом / юриспруденцией, пока что ничего не доступно для вашей платформы или просто более поучительно: копайте и пишите глобальную перегрузку.