(Это довольно большой вопрос о разработке программного обеспечения. Если он не подходит для StackOverflow, я хочу скопировать его в сообщество разработчиков программного обеспечения)
Я работаю с сценарием heap_stat, который исследует отвалы.Этот сценарий основан на идее, что для любого объекта, имеющего виртуальную функцию, поле vftable
всегда является первым (оно позволяет найти адрес в памяти класса объекта).
InВ моих приложениях есть некоторые объекты, имеющие vftable
записей (как правило, каждый объект STL
имеет его), но есть и некоторые объекты, которые этого не делают.
Для того, чтобы вызвать наличие vftable
поле, я сделал следующий тест:
Создайте бессмысленный класс, имеющий виртуальную функцию, и позвольте моему классу наследовать от этого бессмысленного класса:
class NONSENSE {
virtual int nonsense() { return 0; }
};
class Own_Class : public NONSENSE, ...
Это, как и ожидалось, создал запись vftable
в символах, которую я смог найти (используя команду Windbg
s x /2 *!Own_Class*vftable*
):
00000000`012da1e0 Own_Application!Own_Class::`vftable'
Я также увидел разницу в использовании памяти:
sizeof(an normal Own_Class object) = 2928
sizeof(inherited Own_Class object) = 2936
=> 8 байт были добавлены для этого объекта.
Есть одна загвоздка: очевидно, некоторые объекты определены как:
class ATL_NO_VTABLE Own_Class
Этот ATL_NO_VTABLE
блокирует созданиезаписи vftable
, что означает следующее (ATL_NO_VTABLE
равно__declspec(novtable)
):
// __declspec(novtable) is used on a class declaration to prevent the vtable
// pointer from being initialized in the constructor and destructor for the
// class. This has many benefits because the linker can now eliminate the
// vtable and all the functions pointed to by the vtable. Also, the actual
// constructor and destructor code are now smaller.
На мой взгляд, это означает, что vftable
не создается, из-за чего методы объекта вызываются более напрямую, что влияет на скорость выполнения методаи обработка стека.Разрешение на создание vftable
имеет следующее влияние:
Не следует принимать во внимание:
- В стеке есть еще один вызов, который имеет влияние только в случаесистемы, которые уже на пределе использования их памяти.(Я понятия не имею, как компоновщик указывает на конкретный метод)
- Увеличение использования процессора будет слишком маленьким, чтобы его можно было увидеть.
- Уменьшение скорости будет слишком маленьким, чтобы его можно было увидеть.
Следует учитывать:
- Как упоминалось ранее, использование памяти приложением увеличивается на 8 байт на объект.Когда обычный объект имеет размер около 1000 байт, это означает увеличение использования памяти на ± 1%, но для объектов с объемом памяти менее 80 байт это может привести к увеличению использования памяти на + 10%.
Теперь у меня есть следующие вопросы:
- Правильный ли мой анализ воздействия?
- Есть ли лучший способ форсировать создание
vftable
поле, имеющее меньшее влияние? - Я что-то пропустил?
Заранее спасибо