Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2005.07.11;
Скачать: [xml.tar.bz2];

Вниз

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

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

Есть два метода


procedure Dummy1(const aI: IInterface);
begin
  // некая операция с aI
end;

procedure Dummy2(aI: IInterface);
begin
  // некая операция с aI
end;


При вызове Dummy1(TInterfaceObject.Create()) происходит утечка памяти т.к. не отрабатывает деструктор созданного объекта TInterfaceObject.

При вызове Dummy2(TInterfaceObject.Create())  все ок - деструктор отрабатывает корректно.

Это глюк delphi или мой?


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


> Это глюк delphi или мой?


ни твой ни Делфи.

это - ФИЧА (а не баг и не "глюк")

при
const aI: IЧегоТоТам

инкремента интерф.ссылки НЕ происходит,

а при
< aI: IЧегоТоТам

происходит


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


>  [1] Digitman ©   (24.06.05 13:03)

Да это понятно, что фича (cpu я тоже смотреть умею). Только:
1. она нигде не описана
2. она изрядно гадит жизнь (


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


> она нигде не описана


описана.

в справке просто покопаться следует изрядно детальней ... ибо прямой ссылки нет ...


> она изрядно гадит жизнь


ой не ври)

достаточно знать и понимать, что при передаче по const Делфи-компайлер НЕ ответственен за работу со сч-ком ссылок, в то время как во 2-м упомянутом варианте делфи-компайлер вставляет неявный код инкремента (и, если требуется, - декремента) упомянутого сч-ка интерфейсной ссылки

попросту говоря, при const никаких неявных _addref, _release нет, в то время как в упомянутом ином случае они фигурируют (и вполне оправданно)


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

Суслик ©   (24.06.05 13:04) [2]
совершенно логично действует компилятор...


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


> Суслик


а есть ведь еще вариант с

var Intf: IМойИнтерфейс

странно что ты не присовокупил  его к вопросу, ибо так же концептуален он


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


>  [5] Digitman ©   (24.06.05 13:31)

такой вариант работает, есно я это проверил.
В справке про const скорее всего это есть. Но ... читай дальше

----------

... про логичность я бы не стал соглашаться.
Т.к. фактически объект будучи созданным выходит из scope и если дельфи декларирует подсчет ссылок, то это ее дело уничтожать интрефейсы. А то, что я сам решил при передаче в метод не делать подсчет ссылок, это дельфи волновать вообще говоря мало должно - его задача обеспечивать live scope (если уж дельфи за это взялся).


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


> А то, что я сам решил при передаче в метод не делать подсчет
> ссылок, это дельфи волновать вообще говоря мало должно


совершенно верно.

и именно поэтому ты в ДАННОМ случае передаешь свой интерфейс как параметр как const-параметр.... и компилятор при этом НЕ делает никаких неведомых тебе "телодвижений", т.е. все что ты понаписал - полностью прогнозируемо и подконтрольно тебе.


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

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


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

Суслик ©   (24.06.05 14:25) [8]


> либо сделали нормальный garbage collection для интерфейсов.


Java или C# тебе в руки.


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


> Суслик ©   (24.06.05 14:25) [8]


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


а вот тут ты уже начал ужасную чушь пороть)

остановись, вникни, подумай над сабжем !

просмотри, к примеру, sconnect.pas ... остынь) ...
все в этом плане закономерно и правильно !

)


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


> garbage collection для интерфейсов


галиматья полная.

что значит "сборка мусора для интерфейсов" ?

НЕТ в списке существующих где-то там интерфейсов МУСОРА !


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


>  [11] Digitman ©   (24.06.05 14:32)

ладно, давай без всяких там слов "галиматься" и пр.

------------

что будет здесь (ответь не пробуя, только честно)?

procedure e;
begin
  TInterfacedObject.Create();
end;


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


> что будет здесь (ответь не пробуя, только честно)?


конкретно здесь (т.е. при вызове ДАННОЙ процедуры откуда бы то ни было) будет утечка.

тут и "пробовать" ничего не нужно - ты создал объект - экземпляр класса - потерял его адрес в памяти и уничтожить впоследствии, не имея адреса, разумеется не можешь.

класс объекта в дан.случае совершенно неважен.


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


> [10] Digitman ©   (24.06.05 14:30)


> просмотри, к примеру, sconnect.pas ... остынь) ...

Ну да, они все делают через дополнительную локальную переменную:

function TDataBlockInterpreter.CallGetServerList: OleVariant;
var
 Flags: TVarFlags;
 Data: IDataBlock;
begin
 Data := TDataBlock.Create as IDataBlock;
 Data.Signature := CallSig or asGetAppServers;
 Data := FSendDataBlock.Send(Data, True);
 Result := ReadVariant(Flags, Data);
end;


А, кстати, насчет того, что сборка мусора здесь ни при чем я с трудом могу с тобой согласиться. Зачем сделан посчет ссылок? (если не ошибаюсь в ++ его нет). Для того, чтобы было удобно. Но по факту получается так, что приходится помнить условия, при которых подсчет работает верно. Приведенный мной пример не единственный.


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


>  [13] Digitman ©   (24.06.05 14:48)

Согласен, это я что-то налажал :)


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


> [13] Digitman ©   (24.06.05 14:48)


Ладно, закрыто.

Просто запомню, что в данном случае нужно быть осторожней с const.


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


> Ну да, они все делают через дополнительную локальную переменную


врешь)

цитирую :

function TStreamedConnection.Send(const Data: IDataBlock; WaitForResult: Boolean): IDataBlock;
var
 Msg: TMsg;
 Context: Integer;
begin
 if FSupportCallbacks then
 begin
   if not Assigned(FTransport) then Exit;
   Data._AddRef;
   PostThreadMessage(FTransport.ThreadID, THREAD_SENDSTREAM, Ord(WaitForResult),
     Integer(Pointer(Data)));
...



> насчет того, что сборка мусора здесь ни при чем я с трудом
> могу с тобой согласиться. Зачем сделан посчет ссылок?


КАКОЕ отношение имеет механизм подсчета интерф.ссылок к т.н. "сборке мусора" ?

изложи свое вИденье ...


> Для того, чтобы было удобно


Да, конечно.

Мне, к примеру, неудобно, объявив в п/программе лок.переменную MyInterface типа ISomeInterface, заботиться о разрушении объекта, на который в ходе работы моей п/программы эта переменная ВОЗМОЖНО будет ссылаться. а возможно и НЕ будет.

И я с полным пониманием происходящего доверяюсь компилятору, который в ДАННОМ случае вставит неявный код
MyInterface := nil
который , если ссылка <> nil, вызовет за меня, лентяя, метод ISomeInterface._Release, что приведет к разрушению интерф.объекта, если декремент сч-ка в этот момент приведет к нулевому его значению.


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


>  [17] Digitman ©   (24.06.05 15:03)

Речь была про ВЫЗЫВАЮЩУЮ сторону. Я тебе ее процитировал. Т.е. если я не хочу, чтобы у меня в исходном примере были ошибки, то я должен делать также как они.


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


> Суслик ©   (24.06.05 15:06) [18]



> Речь была про ВЫЗЫВАЮЩУЮ сторону


ок.

вызывающая сторона, зная прототип ф-ции с неким интерфейсным параметром (IUnknown или его произвольным наследником) в том или ином виде, обязана иметь четкое представление о том как поступит компилятор.

в случае const или var компилятор НЕ генерирует неявного кода вызова методов _AddRef, _Release передаваемого интерф.объекта

в противном случае компилятор генерирует неявный вызов _AddRef  в контексте "открывающего" п/программу оператора begin и неявный вызов _Release в контексте "закрывающего" п/программу оператора end



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

Форум: "Основная";
Текущий архив: 2005.07.11;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.083 c
14-1118142918
Alexander Panov
2005-06-07 15:15
2005.07.11
Западные ценности. Европейские ценности. Демократия.


6-1112717637
Shaden
2005-04-05 20:13
2005.07.11
Авторизация через Web-форму


1-1118908486
<Lelik>
2005-06-16 11:54
2005.07.11
Про Count


11-1102246493
Silver Dragon
2004-12-05 14:34
2005.07.11
onMouseLeave


5-1088080715
Tor
2004-06-24 16:38
2005.07.11
Панель с кнопками





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский