Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.11;
Скачать: CL | DM;

Вниз

Почему есть утечка памяти при использовании интерфейсов?   Найти похожие ветки 

 
Суслик ©   (2005-06-24 12:59) [0]

Есть два метода <br/><br/><code><br/>procedure Dummy1(const aI: IInterface);<br/>begin<br/> &#xA0; // некая операция с aI<br/>end;<br/><br/>procedure Dummy2(aI: IInterface);<br/>begin<br/> &#xA0; // некая операция с aI<br/>end;<br/></code><br/><br/>При вызове Dummy1(TInterfaceObject.Create()) происходит утечка памяти т.к. не отрабатывает деструктор созданного объекта TInterfaceObject. <br/><br/>При вызове Dummy2(TInterfaceObject.Create()) &#xA0;все ок - деструктор отрабатывает корректно. <br/><br/>Это глюк delphi или мой?


 
Digitman ©   (2005-06-24 13:03) [1]

<i><br/>&gt; Это глюк delphi или мой?<br/></i><br/><br/>ни твой ни Делфи.<br/><br/>это - ФИЧА (а не баг и не &quot;глюк&quot;)<br/><br/>при<br/><u><b>const</b> aI: IЧегоТоТам</u><br/><br/>инкремента интерф.ссылки НЕ происходит,<br/><br/>а при<br/><u>&lt; aI: IЧегоТоТам</u><br/><br/>происходит


 
Суслик ©   (2005-06-24 13:04) [2]

<i><br/>&gt; &#xA0;[1] Digitman © &#xA0; (24.06.05 13:03)<br/></i><br/>Да это понятно, что фича (cpu я тоже смотреть умею). Только:<br/>1. она нигде не описана<br/>2. она изрядно гадит жизнь (


 
Digitman ©   (2005-06-24 13:10) [3]

<i><br/>&gt; она нигде не описана<br/></i><br/><br/>описана.<br/><br/>в справке просто покопаться следует изрядно детальней ... ибо прямой ссылки нет ...<br/><br/><i><br/>&gt; она изрядно гадит жизнь <br/></i><br/><br/>ой не ври)<br/><br/>достаточно знать и понимать, что при передаче по const Делфи-компайлер НЕ ответственен за работу со сч-ком ссылок, в то время как во 2-м упомянутом варианте делфи-компайлер вставляет неявный код инкремента (и, если требуется, - декремента) упомянутого сч-ка интерфейсной ссылки<br/><br/>попросту говоря, при const никаких неявных _addref, _release нет, в то время как в упомянутом ином случае они фигурируют (и вполне оправданно)


 
default ©   (2005-06-24 13:21) [4]

Суслик © &#xA0; (24.06.05 13:04) [2] <br/>совершенно логично действует компилятор...


 
Digitman ©   (2005-06-24 13:31) [5]

<i><br/>&gt; Суслик<br/></i><br/><br/>а есть ведь еще вариант с <br/><br/>var Intf: IМойИнтерфейс<br/><br/>странно что ты не присовокупил &#xA0;его к вопросу, ибо так же концептуален он


 
Суслик ©   (2005-06-24 14:01) [6]

<i><br/>&gt; &#xA0;[5] Digitman © &#xA0; (24.06.05 13:31)<br/></i><br/>такой вариант работает, есно я это проверил. <br/>В справке про const скорее всего это есть. Но ... читай дальше<br/><br/>----------<br/><br/>... про логичность я бы не стал соглашаться. <br/>Т.к. фактически объект будучи созданным выходит из scope и если дельфи декларирует подсчет ссылок, то это ее дело уничтожать интрефейсы. А то, что я <b>сам решил при передаче</b> в метод не делать подсчет ссылок, это дельфи волновать вообще говоря мало должно - его задача обеспечивать live scope (если уж дельфи за это взялся).


 
Digitman ©   (2005-06-24 14:15) [7]

<i><br/>&gt; А то, что я сам решил при передаче в метод не делать подсчет <br/>&gt; ссылок, это дельфи волновать вообще говоря мало должно <br/></i><br/><br/>совершенно верно.<br/><br/>и именно поэтому ты в ДАННОМ случае передаешь свой интерфейс как параметр как const-параметр.... и компилятор при этом НЕ делает никаких неведомых тебе &quot;телодвижений&quot;, т.е. все что ты понаписал - полностью прогнозируемо и подконтрольно тебе.


 
Суслик ©   (2005-06-24 14:25) [8]

убрали бы они вообще нафиг из delphi подсчет ссылок, либо сделали нормальный garbage collection для интерфейсов. Все лучше было бы.


 
Игорь Шевченко ©   (2005-06-24 14:29) [9]

Суслик © &#xA0; (24.06.05 14:25) [8] <br/><br/><i><br/>&gt; либо сделали нормальный garbage collection для интерфейсов.<br/></i><br/><br/>Java или C# тебе в руки.


 
Digitman ©   (2005-06-24 14:30) [10]

<i><br/>&gt; Суслик © &#xA0; (24.06.05 14:25) [8] <br/></i><br/><i><br/>&gt; бы они вообще нафиг из delphi подсчет ссылок, либо сделали <br/>&gt; нормальный garbage collection для интерфейсов<br/></i><br/><br/>а вот тут ты уже начал ужасную чушь пороть)<br/><br/>остановись, вникни, подумай над сабжем !<br/><br/>просмотри, к примеру, sconnect.pas ... остынь) ... <br/>все в этом плане закономерно и правильно !<br/><br/>)


 
Digitman ©   (2005-06-24 14:32) [11]

<i><br/>&gt; garbage collection для интерфейсов<br/></i><br/><br/>галиматья полная.<br/><br/>что значит &quot;сборка мусора для интерфейсов&quot; ?<br/><br/>НЕТ в списке существующих где-то там интерфейсов МУСОРА !


 
Суслик ©   (2005-06-24 14:37) [12]

<i><br/>&gt; &#xA0;[11] Digitman © &#xA0; (24.06.05 14:32)<br/></i><br/>ладно, давай без всяких там слов &quot;галиматься&quot; и пр. <br/><br/>------------<br/><br/>что будет здесь (ответь не пробуя, только честно)?<br/><br/><code>procedure e;<br/>begin<br/> &#xA0; TInterfacedObject.Create();<br/>end;</code>


 
Digitman ©   (2005-06-24 14:48) [13]

<i><br/>&gt; что будет здесь (ответь не пробуя, только честно)?<br/></i><br/><br/>конкретно здесь (т.е. при вызове ДАННОЙ процедуры откуда бы то ни было) будет утечка.<br/><br/>тут и &quot;пробовать&quot; ничего не нужно - ты создал объект - экземпляр класса - потерял его адрес в памяти и уничтожить впоследствии, не имея адреса, разумеется не можешь.<br/><br/>класс объекта в дан.случае совершенно неважен.


 
Суслик ©   (2005-06-24 14:50) [14]

<i><br/>&gt; [10] Digitman © &#xA0; (24.06.05 14:30)<br/></i><br/><i><br/>&gt; просмотри, к примеру, sconnect.pas ... остынь) ... <br/></i><br/>Ну да, они все делают через дополнительную локальную переменную:<br/><br/><code>function TDataBlockInterpreter.CallGetServerList: OleVariant;<br/>var<br/> &#xA0;Flags: TVarFlags;<br/> &#xA0;Data: IDataBlock;<br/>begin<br/> &#xA0;Data := TDataBlock.Create as IDataBlock;<br/> &#xA0;Data.Signature := CallSig or asGetAppServers;<br/> &#xA0;Data := FSendDataBlock.Send(Data, True);<br/> &#xA0;Result := ReadVariant(Flags, Data);<br/>end;</code><br/><br/>А, кстати, насчет того, что сборка мусора здесь ни при чем я с трудом могу с тобой согласиться. Зачем сделан посчет ссылок? (если не ошибаюсь в ++ его нет). Для того, чтобы было удобно. Но по факту получается так, что приходится помнить условия, при которых подсчет работает верно. Приведенный мной пример не единственный.


 
Суслик ©   (2005-06-24 14:52) [15]

<i><br/>&gt; &#xA0;[13] Digitman © &#xA0; (24.06.05 14:48)<br/></i><br/>Согласен, это я что-то налажал :)


 
Суслик ©   (2005-06-24 14:57) [16]

<i><br/>&gt; [13] Digitman © &#xA0; (24.06.05 14:48)<br/></i><br/><br/>Ладно, закрыто. <br/><br/>Просто запомню, что в данном случае нужно быть осторожней с const.


 
Digitman ©   (2005-06-24 15:03) [17]

<i><br/>&gt; Ну да, они все делают через дополнительную локальную переменную<br/></i><br/><br/>врешь)<br/><br/>цитирую :<br/><br/><code>function TStreamedConnection.Send(<b>const</b> Data: IDataBlock; WaitForResult: Boolean): IDataBlock;<br/>var<br/> &#xA0;Msg: TMsg;<br/> &#xA0;Context: Integer;<br/>begin<br/> &#xA0;if FSupportCallbacks then<br/> &#xA0;begin<br/> &#xA0; &#xA0;if not Assigned(FTransport) then Exit;<br/> &#xA0; &#xA0;Data._AddRef;<br/> &#xA0; &#xA0;PostThreadMessage(FTransport.ThreadID, THREAD_SENDSTREAM, Ord(WaitForResult),<br/> &#xA0; &#xA0; &#xA0;Integer(Pointer(Data)));<br/>...</code><br/><br/><i><br/>&gt; насчет того, что сборка мусора здесь ни при чем я с трудом <br/>&gt; могу с тобой согласиться. Зачем сделан посчет ссылок?<br/></i><br/><br/>КАКОЕ отношение имеет механизм подсчета интерф.ссылок к т.н. &quot;сборке мусора&quot; ?<br/><br/>изложи свое вИденье ...<br/><br/><i><br/>&gt; Для того, чтобы было удобно<br/></i><br/><br/>Да, конечно.<br/><br/>Мне, к примеру, неудобно, объявив в п/программе лок.переменную MyInterface типа ISomeInterface, заботиться о разрушении объекта, на который в ходе работы моей п/программы эта переменная ВОЗМОЖНО <u>будет</u> ссылаться. а возможно и <u>НЕ будет</u>.<br/><br/>И я с полным пониманием происходящего доверяюсь компилятору, который в ДАННОМ случае вставит неявный код <br/>MyInterface := nil<br/>который , если ссылка &lt;&gt; nil, вызовет за меня, лентяя, метод ISomeInterface._Release, что приведет к разрушению интерф.объекта, если декремент сч-ка в этот момент приведет к нулевому его значению.


 
Суслик ©   (2005-06-24 15:06) [18]

<i><br/>&gt; &#xA0;[17] Digitman © &#xA0; (24.06.05 15:03)<br/></i><br/>Речь была про ВЫЗЫВАЮЩУЮ сторону. Я тебе ее процитировал. Т.е. если я не хочу, чтобы у меня в исходном примере были ошибки, то я должен делать также как они.


 
Digitman ©   (2005-06-24 15:19) [19]

<i><br/>&gt; Суслик © &#xA0; (24.06.05 15:06) [18] <br/></i><br/><br/><i><br/>&gt; Речь была про ВЫЗЫВАЮЩУЮ сторону<br/></i><br/><br/>ок.<br/><br/>вызывающая сторона, зная прототип ф-ции с неким интерфейсным параметром (IUnknown или его произвольным наследником) в том или ином виде, обязана иметь четкое представление о том как поступит компилятор.<br/><br/>в случае const или var компилятор <b>НЕ</b> генерирует неявного кода вызова методов _AddRef, _Release передаваемого интерф.объекта<br/><br/>в противном случае компилятор генерирует <u>неявный</u> вызов _AddRef &#xA0;в контексте &quot;открывающего&quot; п/программу оператора <b>begin</b> и <u>неявный</u> вызов _Release в контексте &quot;закрывающего&quot; п/программу оператора <b>end</b>



Страницы: 1 вся ветка

Текущий архив: 2005.07.11;
Скачать: CL | DM;

Наверх




Память: 1.32 MB
Время: 0.037 c
14-1118480066
Cheater
2005-06-11 12:54
2005.07.11
Программирование в Excele. Как скрыть строки?


3-1117024028
evg00
2005-05-25 16:27
2005.07.11
последняя запись


14-1118596069
le[x]
2005-06-12 21:07
2005.07.11
Помогите с курсовой


3-1117141875
Zahar
2005-05-27 01:11
2005.07.11
Помогите с SQL-запросом.


11-1084224094
Диман
2004-05-11 01:21
2005.07.11
TabControl и ширина кнопок