Использование tcmalloc — Как правильно загрузить расширения malloc?

В файле gperftools-2.2.1 / src / gperftools / malloc_extension.h он гласит:

// Extra extensions exported by some malloc implementations.  These
// extensions are accessed through a virtual base class so an
// application can link against a malloc that does not implement these
// extensions, and it will get default versions that do nothing.
//
// NOTE FOR C USERS: If you wish to use this functionality from within
// a C program, see malloc_extension_c.h.

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

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

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

…загрузка библиотеки замены malloc через dlopen
В любом случае возникнут проблемы: некоторые данные будут размещены с одним malloc, некоторые с другим.

Так что явно доступ к расширениям обычным способом, как упомянуто выше, не вариант. Я могу обойтись без использования версий C, как объявлено в malloc_extensions_c.h, но просто задаюсь вопросом, есть ли какое-либо лучшее решение.

3

Решение

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

Во-первых, большинство этих функций расширения malloc аналогичны статическим функциям в том смысле, что они в основном вызываются только в текущем экземпляре, например позвонить GetMemoryReleaseRate() функция текущего процесса, который вы просто называете MallocExtension::instance()->GetMemoryReleaseRate(), Поэтому нам не нужно создавать базовый класс и получать экземпляр класса MallocExtension для вызова этих функций.

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

getMemoryReleaseRate()
{
MallocExtension::instance()->GetMemoryReleaseRate();
}

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

Теперь в своем коде вы можете вызывать функцию MallocExtension через функцию ‘фасад’, которую вы создали с помощью dlsym (), например, как показано ниже:

typedef void (*getMemoryReleaseRate)();
((getMemoryReleaseRate)dlsym(RTLD_DEFAULT, "getMemoryReleaseRate"))();
0

Другие решения

Просто включив этот заголовок и выполнив MallocExtension :: instance () -> GetMemoryReleaseRate (); будет работать тоже. Для этого не нужно изменять tcmalloc.

0

По вопросам рекламы [email protected]