Я пытаюсь оптимизировать размер моих классов Delphi, чтобы они занимали как можно меньше памяти, потому что я их создаю.
Дело в том, что сами классы довольно маленькие, но они не занимают места, которое я ожидал. Например, если у меня есть
type MyClass = class
private
mMember1 : integer;
mMember2 : boolean;
mMember3 : byte;
end;
Я ожидаю, что он будет использовать 6 байтов, но из-за выравнивания он заканчивается использованием 12 байтов, то есть логические значения используют 4 байта вместо 1 байта ... и то же самое относится к полю байтов ...
Для записей вы можете использовать директиву {$ A1} или объявить ее как упакованную запись, чтобы она использовала только необходимую память.
Есть ли способ сделать то же самое с классами? (Может быть, какое-нибудь руководство о том, как правильно переопределить метод класса NewInstance?)
Редактировать: Хорошо, небольшое объяснение того, что я делаю ...
Во-первых, реальный размер класса составляет около 40 байтов, включая пространство, занимаемое VMT и указателями интерфейса.
Все классы наследуются от базового класса RefCounting, размер которого составляет 8 байтов (целое число FRefCount и некоторые методы для подсчета ссылок), и они ДОЛЖНЫ поддерживать интерфейсы (следовательно, вообще не использовать упакованные записи).
Эти объекты передаются и превращаются в несколько вещей, при этом обработчики не знают, что они получили. Например, у меня есть класс, который получает список элементов и выполняет что-то вроде:
if Supports(List[i], IValuable, IValInstance) then
Eval(IValInstance.Value);
тогда другой обработчик может проверить другой интерфейс
If Supports(List[i], IStringObject, IStringInstance) then
Compose(IStringInstance.Value)
Таким образом, список обрабатывается по-разному каждым обработчиком ...
О том, как получить общий размер класса, я использую модифицированный менеджер памяти, чтобы я мог отслеживать, сколько памяти использует «настоящий» менеджер памяти для класса. Таким образом, я уверен, что экземпляры не упаковываются.
Наконец, это в Delphi 7. Я безуспешно пытался использовать директиву прекомпилятора {$ A1}, поля в любом случае выровнялись, и в худшем случае я могу иметь несколько миллионов экземпляров, так что сохранение 6 байтов может результат на нескольких МБ сохраняется.