procedure TfrmTC_MainEditor.FormCreate(Sender: TObject);
begin
ReportMemoryLeaksOnShutdown := True;
end;
Написав такую штуку после закрытия приложения, если в нем есть утечки памяти, появиться диалоговое окно показывающее сколько памяти "утекло".
У меня есть отдельный модуль PAUT_SettingUtils.pas который не подключен в проект, просто юзается так как он прописан в путях "Lib Path" (не помню точно как оно называется, но думаю что все меня поняли).
В нем есть код
unit PAUT_SettingUtils;
interface{
код
}implementation
uses{...};
var SettingCommonFile : String; // Эти значения инициализируются в разделе initialization
SettingCurrentUser : String;{
Куча кода
}initialization
SettingCommonFile := 'Settings.ini';
SettingCurrentUser := NormalDir(GetMyDocumentsFolder) + 'Settings.ini';
end.
Так после закрытия приложения говорилось что у меня есть 2 утечки памяти.
И я обнаружил если написать в этом модуле так
unit PAUT_SettingUtils;
interface{
код
}implementation
uses{...};
var SettingCommonFile : String = ''; // Эти значения инициализируются в разделе initialization
SettingCurrentUser : String = '';{
Куча кода
}initialization
SettingCommonFile := 'Settings.ini';
SettingCurrentUser := NormalDir(GetMyDocumentsFolder) + 'Settings.ini';
end.
То утечки памяти перестаю быть. Кто нибудь может объяснить почему в первом случае получаются утечки памяти?
J>утечек нет. Выводы предлагаю сделать самому
И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
Здравствуйте, konst, Вы писали:
J>>утечек нет. Выводы предлагаю сделать самому K>И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
Здравствуйте, Jack128, Вы писали:
J>Здравствуйте, konst, Вы писали:
J>>>утечек нет. Выводы предлагаю сделать самому K>>И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
J>А где ты их освобождаешь?
Здравствуйте, FDSC, Вы писали:
FDS>Здравствуйте, Jack128, Вы писали:
J>>Здравствуйте, konst, Вы писали:
J>>>>утечек нет. Выводы предлагаю сделать самому K>>>И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
J>>А где ты их освобождаешь?
FDS>По идее String должен её сам освобождать...
Вот вот! Наример:
type
TSome = class
public
s: String;
end;
procedure DoSome;
var
a: String;
b: TSome;
begin
a := 'aaaaaaaaaaaaaaaaaa';
b := TSome.Create;
try
b.s := a;
finally
b.Free; // освобождается память, занятая "b.s = 'aaaaaaaaaaaaaaaaaa'"end;
end; // освобождается память, занятая "a = 'aaaaaaaaaaaaaaaaaa'"
Здравствуйте, konst, Вы писали:
J>>утечек нет. Выводы предлагаю сделать самому K>И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
Да уничтожается все, вызывается системная функция _FinalizeRecord для класов, посмотрите на метод CleanupInstance. Тут скорее траблы с initialization/finalization секциями что то компилятор не удосужился слинковать, честно влом сейчас разбираться, посмотрите дизасемблером сами.
Здравствуйте, Danchik, Вы писали:
D>Здравствуйте, konst, Вы писали:
J>>>утечек нет. Выводы предлагаю сделать самому K>>И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
D>Да уничтожается все, вызывается системная функция _FinalizeRecord для класов, посмотрите на метод CleanupInstance. Тут скорее траблы с initialization/finalization секциями что то компилятор не удосужился слинковать, честно влом сейчас разбираться, посмотрите дизасемблером сами.
Весело! Пришол ни с того ни с сего человек и сказал вдруг: "мне влом разбираться, смотри дизассемблер сам". Ну, спасибо! Всё сказанное тобой и так понятно. Другое дело, что в данном случае память освобождать и не надо, эта ошибка фиксируется, да, но ни на что не влияет.
Здравствуйте, konst, Вы писали:
K>Здравствуйте, Danchik, Вы писали:
D>>Здравствуйте, konst, Вы писали:
J>>>>утечек нет. Выводы предлагаю сделать самому K>>>И какие же? С какого фига при уничтожении объектов типа String захваченная ими память не освобождается? Просто интересно, а если есть такие переменные-мемберы классов, то тоже память не освобождается при уничтожении экземпляра класса?
D>>Да уничтожается все, вызывается системная функция _FinalizeRecord для класов, посмотрите на метод CleanupInstance. Тут скорее траблы с initialization/finalization секциями что то компилятор не удосужился слинковать, честно влом сейчас разбираться, посмотрите дизасемблером сами. K>Весело! Пришол ни с того ни с сего человек и сказал вдруг: "мне влом разбираться, смотри дизассемблер сам". Ну, спасибо! Всё сказанное тобой и так понятно.
Ну так что ж вы тут флейм разводите если все понятно. Я же вам говорю что глючит логика компилятора. Мне не интересно, пока, вот и предлагаю разобраться самим. В finalization должен быть создан компилятором соответствующий код, чистящий переменную. И я догадываюсь почему его нет, иначе юниты, сожержащие стринговые глобальные переменные, не могли бы быть скомпилированы как WeekPackage unit. Так как эти юниты не должны содержать инициализационных секций.
K>Другое дело, что в данном случае память освобождать и не надо, эта ошибка фиксируется, да, но ни на что не влияет.
Гы, ну естественно ни на что не влияет в EXE. А вот Run-Time packages может и повлиять если ипользовать позднюю загрузку/выгрузку — будет лик.
K>>Другое дело, что в данном случае память освобождать и не надо, эта ошибка фиксируется, да, но ни на что не влияет. D>Гы, ну естественно ни на что не влияет в EXE. А вот Run-Time packages может и повлиять если ипользовать позднюю загрузку/выгрузку — будет лик.
Не обязательно.
Вполне вероятно, что все юниты, включая fastmm, финализируются до уничтожения глобальных переменных.
И уже после выдачи этого сообщения переминная таки зачищается
Здравствуйте, Arioch, Вы писали:
K>>>Другое дело, что в данном случае память освобождать и не надо, эта ошибка фиксируется, да, но ни на что не влияет. D>>Гы, ну естественно ни на что не влияет в EXE. А вот Run-Time packages может и повлиять если ипользовать позднюю загрузку/выгрузку — будет лик.
A>Не обязательно.
A>Вполне вероятно, что все юниты, включая fastmm, финализируются до уничтожения глобальных переменных. A>И уже после выдачи этого сообщения переминная таки зачищается
Не думаю что Delphi разкидывает финализацию.
Я, кстати, протестил, действительно память освобождается. Все тут гуд. WEAKPACKAGEUNIT на юнит со стринговой глобальной переменной не сделать. Скорее всего действительно финализация ловителя ликов сработала быстрее, чем вызвалась финализация тестируемого юнита.
A>>Вполне вероятно, что все юниты, включая fastmm, финализируются до уничтожения глобальных переменных. A>>И уже после выдачи этого сообщения переминная таки зачищается
D>Не думаю что Delphi разкидывает финализацию. D>Я, кстати, протестил, действительно память освобождается. Все тут гуд. WEAKPACKAGEUNIT на юнит со стринговой глобальной переменной не сделать. Скорее всего действительно финализация ловителя ликов сработала быстрее, чем вызвалась финализация тестируемого юнита.
Я думаю что более того — сначала финализируются все юниты, а уже потом финализируются глобальные переменные.
На то они и глобальные однако — пока самый распослений бнит не финализировался — как монжо с уверенностью сказать что эта переменная больше не будет никем использоваться и ее уже безопасно зачищать ? Только когда все модули включая library/program/package уже финализированы — тогда уничтожать *гглобальные* всем доступные переменные становится безопасно.
Здравствуйте, Arioch, Вы писали:
A>>>Вполне вероятно, что все юниты, включая fastmm, финализируются до уничтожения глобальных переменных. A>>>И уже после выдачи этого сообщения переминная таки зачищается
D>>Не думаю что Delphi разкидывает финализацию. D>>Я, кстати, протестил, действительно память освобождается. Все тут гуд. WEAKPACKAGEUNIT на юнит со стринговой глобальной переменной не сделать. Скорее всего действительно финализация ловителя ликов сработала быстрее, чем вызвалась финализация тестируемого юнита.
A>Я думаю что более того — сначала финализируются все юниты, а уже потом финализируются глобальные переменные. A>На то они и глобальные однако — пока самый распослений бнит не финализировался — как монжо с уверенностью сказать что эта переменная больше не будет никем использоваться и ее уже безопасно зачищать ? Только когда все модули включая library/program/package уже финализированы — тогда уничтожать *гглобальные* всем доступные переменные становится безопасно.
Как это ни печально но глобальная переменная финализируется именно в финализационной секции. Просто посмотрел в Disassembler. Delphi старается вызывать finalization в нужном порядке. Тоесть юниты финализируется только после того как пройдет финализация всех юнитов которые ее используют.
D>Как это ни печально но глобальная переменная финализируется именно в финализационной секции. Просто посмотрел в Disassembler. Delphi старается вызывать finalization в нужном порядке. Тоесть юниты финализируется только после того как пройдет финализация всех юнитов которые ее используют.
Любопытно! и как-то криво...
а если у меня взаимная зависимость unit1 и unit2 в implementation uses ?
Здравствуйте, Arioch, Вы писали:
D>>Как это ни печально но глобальная переменная финализируется именно в финализационной секции. Просто посмотрел в Disassembler. Delphi старается вызывать finalization в нужном порядке. Тоесть юниты финализируется только после того как пройдет финализация всех юнитов которые ее используют.
A>Любопытно! и как-то криво...
A>а если у меня взаимная зависимость unit1 и unit2 в implementation uses ?
A>Мда
Именно, что криво, у меня иногда падало черт знает почему. Спасал только Build — поправлялся порядок вызова finalization.
BTW, глобальные переменные — зло. Для такого дела я всегда использую синглтоны.