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

Вниз

Размер объекта в памяти   Найти похожие ветки 

 
RealRascal ©   (2004-04-27 22:46) [0]

Есть, например, потомок от TObject. С какими-то property и проч. Как узнать, сколько он занимает памяти? Как узнать, что ОЗУ коррекно высвободилось после его уничтожения?


 
Игорь Шевченко ©   (2004-04-27 22:51) [1]


> Как узнать, сколько он занимает памяти?


TObject.InstanceSize


> Как узнать, что ОЗУ коррекно высвободилось после его уничтожения?


Какая может быть некорректность ?


 
Jack128 ©   (2004-04-27 22:54) [2]


> Как узнать, что ОЗУ коррекно высвободилось после его уничтожения?
если при вызове деструктора не было исключений, то все ОК.

Вообще для отслеживания утечек памяти есть специальные программы, например Memproof


 
Юрий Зотов ©   (2004-04-27 23:17) [3]

> RealRascal ©   (27.04.04 22:46)  

> Как узнать, что ОЗУ коррекно высвободилось после его
> уничтожения?

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


 
Jack128 ©   (2004-04-27 23:19) [4]


> а не супергениальным начальником статистиков
перегибаете палку...


 
Юрий Зотов ©   (2004-04-27 23:48) [5]

> Jack128 ©   (27.04.04 23:19) [4]

Это уже имя нарицательное. Так что вряд ли.


 
RealRascal ©   (2004-04-28 01:32) [6]


> Юрий Зотов ©   (27.04.04 23:17) [3]


> Jack128 ©   (27.04.04 23:19) [4]


> Юрий Зотов ©   (27.04.04 23:48) [5]

не посвящен в эти интриги
к щастью для себя

НЕ знаю кем написано то, что я использую, но что-то как то не очень оно освобождается...

Скорее по-своему переписать придется...

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

Вот еще вариант:
я процессе выполнения использую функции, результатом которых являются те самые объекты. в этих функциях объект создается(иногда и не один) а затем один из них становится результатом этой функции. другие destroy. Эта функция присваевается объекту того же класса(есстественно). Может ли при этом происходить утечка памяти? При присвоении один из объектов должен занять место другого (в памяти), ведь так? Или другой после этого надо тоже уничтожить?Но по-моему объект - это указатель, и если мы после

A:=B;

очистим B, то и A окажется пустым. Так?


 
default ©   (2004-04-28 01:39) [7]

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


 
RealRascal ©   (2004-04-28 01:50) [8]

тут все на дельфи
хотя.... есть фстафки на асме


 
Игорь Шевченко ©   (2004-04-28 10:34) [9]


> Но по-моему объект - это указатель, и если мы после
>
> A:=B;
>
> очистим B, то и A окажется пустым. Так?


значением А будет недействительная ссылка.


 
Jack128 ©   (2004-04-28 12:01) [10]


> НЕ знаю кем написано то, что я использую, но что-то как
> то не очень оно освобождается...

TTest = class
 p: PChar;
publilc
 constructor Create;
end;

constructor TTest.Create;
begin
 inherited;
 p := AllocMem(100);
end;

Например такой класс конечно вызывает утечку памати, и что самое главное без переписывания класса ты никак не сможешь эту утечку прекратить. Так что либо пинай автора класса, либо сам переписывай..


 
Jack128 ©   (2004-04-28 12:02) [11]


> НЕ знаю кем написано то, что я использую, но что-то как
> то не очень оно освобождается...

TTest = class
 p: PChar;
publilc
 constructor Create;
end;

constructor TTest.Create;
begin
 inherited;
 p := AllocMem(100);
end;

Например такой класс конечно вызывает утечку памати, и что самое главное без переписывания класса ты никак не сможешь эту утечку прекратить. Так что либо пинай автора класса, либо сам переписывай..


 
Юрий Зотов ©   (2004-04-28 12:07) [12]

> RealRascal ©   (28.04.04 01:32) [6]

Тут есть тонкость. Если A - переменная (или поле, или свойство другого объекта с прямым доступом по записи), то после уничтожения B освободится вся память и A будет битой ссылкой. Но если A - это свойство другого объекта и имеет метод Set, в котором  вызывается Assign, то после уничтожения B объект A останется вполне рабочим. В этом случае об уничтожении A должен позаботиться объект, владеющий свойством A.


 
RealRascal ©   (2004-05-01 19:48) [13]

Вот так оно у них создается и освобождается.

constructor TDensMatrix.Create(ARow, AClmn:integer; AElemOrd:TElemOrd; ATypeEl:TTypeEl; const AName:String);
begin
inherited Create(ATypeEl, AName);
FElemOrd:=AElemOrd; FRows:=ARow; FColumns:=AClmn;
SetMN;
FData:=AllocMem(Am*SizeElem[tePointer]);
AllocMemElements;
end;

destructor TTemplateMatrix.Destroy;
begin
FreeData;
inherited Destroy;
end;

procedure TDensMatrix.FreeData;
var I:integer;
begin
if Assigned(FData) then
 begin
  for I:=1 to Am do
   if Assigned(AP1(FData^)[I]) then FreeMem(AP1(FData^)[I]);
  FreeMem(FData);
  FData:=nil;
 end;
end;


Могут ли тут быть разного рода утечки?


 
Palladin ©   (2004-05-01 19:56) [14]

ну если тип AP1 есть array [0.. утечка имеет место быть+ AV, если же [1.. то утечек может и не быть а может и быть, не видно текста AllocMemElements


 
RealRascal ©   (2004-05-01 20:00) [15]

Как вы могли догадаться, TDensMatrix порожден от TTemplateMatrix.

И чуть не забыл, чтобы не ущемить ничьих прав,
заголовок юнита

{Избранные алгоритмы линейной алгебры LA V1.0.
Пирогов А.В. 2003 г.
При при написании использовались:

Уилкинсон, Райнш Справочник по алгоритмам на языке АЛГОЛ. Линейная алгебра.
Пер. с англ. Под ред. Ю.И. Топчеева. М. "Машиностроение", 1976 г.

W. H. Press, S. A. Teukolsky, W. T. Vetterling, B. P. Flannery Numerical Recipes in
Fortran 77. The Art of Scientific Computing. Second Edition  V.1

BLAS (Basic Linear Algebra Subprograms) www.netlib.org/blas

LAPACK -- Linear Algebra PACKage www.netlib.org/lapack
}


 
RealRascal ©   (2004-05-01 20:50) [16]


> Palladin ©   (01.05.04 19:56) [14]


procedure TDensMatrix.AllocMemElements;
var I:integer;
begin
for I:=1 to Am do AP1(FData^)[I]:=AllocMem(SizeRC);
end;


 
RealRascal ©   (2004-05-03 11:14) [17]

Провел ряд экспериментов.
Данный код НЕ приводит к утечке памяти:
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
   m1,m2:TDensMatrix;
begin
  for i:=1 to 100 do begin
                     m1:=TDensMatrix.Create(1000,1000,eoRow,teDouble,"");
                     m1.Destroy;
                     end;
end;

Следовательно, у них там все ОК с высвобождением.
А вот этот код ПРИВОДИТ к утечкам памяти:
procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
   m1,m2:TDensMatrix;
begin
  for i:=1 to 100 do begin
                     m1:=TDensMatrix.Create(1000,1000,eoRow,teDouble,"");
                     m1:=Trans(m1);
                     m1.Destroy;
                     end;
end;

Очевидно, что все дело в функции trans(), которая, видимо, свидетельствует о моей криворукости :(:
function Trans(const A: TDensMatrix): TDensMatrix;
var i, j: word;
 ca: double;
begin
 Result := TDensMatrix.Create(A.Columns, A.Rows, eorow, a.TypeEl, A.name + "T");
     for i := 1 to a.rows do
     begin
       for j := 1 to a.columns do
       begin
         a.Get(ca, i, j);
         Result.Put(ca, j, i);
       end;
     end;
end;


Я не понимаю, почему так происходит. Догадываюсь, наверняка из-за того, что в функции создается объект. Но ведь потом он присваивается другому объекту! Я понимаю так, что при этом он должен занять его место в памяти, так?
Как этого избежать? Использовать процедуры, и передавать в них эти объекты как параметры? Это было бы не совсем удобно


 
SPeller ©   (2004-05-03 12:06) [18]

procedure TForm1.Button1Click(Sender: TObject);
var i:integer;
  m1,m2:TDensMatrix;
begin
 for i:=1 to 100 do begin
                    m1:=TDensMatrix.Create(1000,1000,eoRow,teDouble,"");
                    m2:=Trans(m1);
                    m1.Destroy;
                    ...
                    m2.Destroy;
                    end;
end;


 
RealRascal ©   (2004-05-03 12:44) [19]


> SPeller ©   (03.05.04 12:06) [18]

результат аналогичный.


 
SPeller ©   (2004-05-03 14:49) [20]

По крайней мере приведённый код НЕ должен вызывать утечек. Они могут быть, например, в методах Get и Put класса TDensMatrix. Потому что один экземпляр создается m1:=TDensMatrix.Create(1000,1000,eoRow,teDouble,"");, второй в методе Trans Result := TDensMatrix.Create(A.Columns, A.Rows, eorow, a.TypeEl, A.name + "T");, а затем оба уничтожаются ....... Гы :) Не Destroy надо использовать, а Free :)))


 
RealRascal ©   (2004-05-03 15:30) [21]

Попробуем


 
RealRascal ©   (2004-05-03 16:29) [22]

Сделал вот так
for i:=1 to 100 do begin
                    m1:=TDensMatrix.Create(1000,1000,eoRow,teDouble,"");
                    m2:=TDensMatrix.Create(1000,1000,eoRow,teDouble,"");
                    m2:=Trans(m1);
                    m1.free;
                    m2.free;
                    end;

все также


 
SPeller ©   (2004-05-03 17:45) [23]

Этого НЕ НАДО: m2:=TDensMatrix.Create(1000,1000,eoRow,teDouble,""); !!!


 
RealRascal ©   (2004-05-03 19:35) [24]

Спасибо, ситуация прояснилась.
Вот что я вынес из всего этого:
При присваивании одного(источник) объекта другому(реципиент) необходимо чтобы реципиент был пустой, а если не он пустой, то нужно его очистить. Если этого не сделать, то кусок информации, который он занимал, так и будет болтаться в памяти, и доступ к нему потеряется, поскольку ссылка на него затерта ссылкой на источник.

Интересно, это баг обжект паскаля?


 
Anatoly Podgoretsky ©   (2004-05-03 19:38) [25]

Нет, Object Pascal ни причем.


 
RealRascal ©   (2004-05-03 19:41) [26]

Есть ли цивилизованные методы борьбы с этим?


 
RealRascal ©   (2004-05-03 22:08) [27]

Как сделать, что в классе прописать, чтобы при присвоении одного экземпляра другому, область памяти, принадлежавшая ему, становилась занятой новым экземпляром?


 
Jack128 ©   (2004-05-03 22:15) [28]


> Как сделать, что в классе прописать, чтобы при присвоении
> одного экземпляра другому, область памяти, принадлежавшая
> ему, становилась занятой новым экземпляром?
А старый экземпляр куда? Уничтожать?


 
default ©   (2004-05-03 22:37) [29]

читая книгу по COM, там все примеры на C++, вот там подобное делается через smart-указатели...круто, можно переопределить по-моему любой оператор(=,:= и тд.)
типа того как работа ведётся с интерфейсными переменными в Delphi
RealRascal ©   (03.05.04 19:41) [26]
только через "оболочки" типа
Assign_(var ObjDest: TObject; ObjSource: TObject);
begin
if Assign(ObjDest) then ObjDest.Destroy;
ObjDest := ObjSource
end;


 
RealRascal ©   (2004-05-03 22:40) [30]


> default ©   (03.05.04 22:37) [29]

пасиб за мысль. щас попробую реализовать


 
RealRascal ©   (2004-05-05 16:47) [31]

Все! всем спасибо! решил проблему так: перед присвоением освобождаю объект, которому хочу присвоить другой объект... Понять, что надо делать именно так, стоило мне двух дней...
На что только не грешил... думал, может создатели юнита плохо постарались... зря.. они молодцы... Это все моя неопытпость...
Отдельная благодарность:
SPeller ©  
default ©



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

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

Наверх





Память: 0.54 MB
Время: 0.043 c
7-1082023124
Rikki
2004-04-15 13:58
2004.05.23
Как заблокировать компьютер а тоесть......


14-1083579274
Undert
2004-05-03 14:14
2004.05.23
Services


14-1083516596
Maxim Vetera
2004-05-02 20:49
2004.05.23
Заглядывая в будущее!


8-1078386896
Petro
2004-03-04 10:54
2004.05.23
Подскажите компонент "Далее-Назад" Wizard!


1-1084056228
RiKo
2004-05-09 02:43
2004.05.23
Как получить в Currency то что находится до запятой и после?





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский