2016-01-20 1 views
1

Я использую инструмент MapFileStats для проверки сгенерированных файлов карт из delphi. Я обнаружил, что анонимные методы генерируют какие-то метаданные, которые, похоже, не связаны с RTTI. Что это за метаданные? Было бы неплохо удалить его, потому что в нашей производственной среде он суммируется до очень больших размеров.Какие метаданные генерируются анонимными методами? И есть ли способ удалить его?

Пример кода:

program RttiDemo; 

{$APPTYPE CONSOLE} 
{$R *.res} 

uses 
    System.SysUtils; 

{$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])} 
{$WEAKLINKRTTI OFF} 

var 
    AProc: TProc; 

begin 
    try 

    AProc := procedure() 
     begin 
     // ... 
     end; 

    except 
    on E: Exception do 
     WriteLn(E.ClassName, ': ', E.Message); 
    end; 

end. 

Скриншот из MapFileStats:

Screenshot displaying MailFileStats

Другой пример:

program RttiDemo; 

{$APPTYPE CONSOLE} 
{$R *.res} 

uses 
    System.SysUtils; 

{$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])} 
{$WEAKLINKRTTI OFF} 

type 

    TDemo = class 
    procedure Demo(); 
    end; 

procedure TDemo.Demo; 
var 
    AProc: TProc; 
begin 
    AProc := procedure() 
    var 
     i: Integer; 
    begin 
     i := 5; 
     WriteLn(i); 
    end; 

    AProc(); 
end; 

var 
    Demo: TDemo; 

begin 
    Demo := TDemo.Create(); 
    try 
    Demo.Demo; 
    finally 
    FreeAndNil(Demo); 
    end; 
end. 

Скриншот:

another MapFileStats screenshot

ответ

2

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

Ниже будет испускать имя класса объекта, который реализует анонимный метод:

Writeln((IInterface(Pointer(@AProc)^) as TObject).ClassName); 

При добавлении к вашей второй программе, выход:

TDemo.Demo$0$ActRec 

Это то же имя, которое вы выделили в вопросе.

+0

На первый взгляд этот вопрос выглядит глупо. Но: мы используем общие списки и в соответствии с инструментом 'TList .Pack' генерирует много этих метаданных, потому что он создан для каждого типа общего списка. Я думаю, что для такого базового родового класса это должно быть реализовано без этих накладных расходов! – ventiseis

+0

Я могу понять, откуда вы это делаете. Тем не менее, я действительно не думаю, что есть много, что вы можете с этим поделать. Вы сообщили об этом Embarcadero? Какая часть вашего исполняемого размера состоит из классов методов anon? –

+0

Я не могу дать вам точный номер, в этом инструменте нет функции экспорта. Самая большая единица (скомпилированный размер 1,8 МБ в соответствии с инструментом) получает до 5% метаданных и реализации (в сочетании) только для метода «Pack». Но я не понимаю другого: для этого конкретного устройства (у которого нет файла .dfm) размер файла на диске составляет 17 МБ. Таким образом, существует другая разница между файлом карты и dcu. Есть ли инструмент для анализа скомпилированных файлов dcu? – ventiseis

Смежные вопросы