Re: освобождение памяти при работе с динамическими объектами
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 10.09.03 10:41
Оценка:
Здравствуйте, vedmalex, Вы писали:

V>Проблема заключается в следующем:

V>Есть прога — модель СМО(ситсемы массового обслуживания) а конкретно модель СУБД.
V>Все прекрасно работает без исключений и прочее.
V>Моделирование: все элементы модели Объкты дерево. Динамически путем копирования создаются структуры типа запросы, которые далее удаляются в одном из блоков. Удаляется все тоже по правилам по всем. НО полсе создания примерно 450 000 штук запросов(объектов типа запрос) размер ОП выделяемой программой увеличивается на 120 М получается что структура размером 300 байт не удаляется вопреки ожиданиям. После завершения программы размер свободной ОП восстанавливается.
V>Т.е. я понимаю что после вызова деструктора память не освобождаемтся.
V>Я так понимаю, все объекты типа наслеуемые от TObject являются динамичесмкими — размещаются в "КУЧЕ". Если не так поправьте меня.

V>Вопрос каким образом заставить ОС или программу освобождать память после удаления объектов.


1) Менеджер памяти Delphi возвращает системе все свободный блоки, размер которых >= 15 Кб.
2) С другой стороны возможна (хотя и маловероята) фрагментация блоков.
3) Я бы рекомендовал в первую очередь оценить ситуацию с менеджером памяти Delphi. Для этого надо вызвать функцию GetHeapStatus, а нам сообщить значения элементов структуры THeapStatus. Во вском случае, "получается что структура размером 300 байт не удаляется вопреки ожиданиям" это только предположение.
Re[3]: освобождение памяти при работе с динамическими объект
От: Prinzip  
Дата: 10.09.03 10:44
Оценка:
vector<TMyComponent2*> allA;

Создаем

{
TMyComponent2 *A = new TMyComponent2(Form1,Form1);
allA.push_back();
}

Удаляем

{
for(unsigned int i=0; i<allA.size();i++)
delete allA[i];
allA.clear();
}
Re[9]: освобождение памяти при работе с динамическими объект
От: Sinclair Россия https://github.com/evilguest/
Дата: 10.09.03 11:36
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

LT> Процедуры(глобальные) этого модуля принимают первым параметром указатель на обрабатываемую запись.

LT> Конечно, писать приходится немного больше, чем в случае объектов, но логика практически такая же.
LT> Также это облегчает создание истинно объектной оболочки (если она вдруг потребуется), путем написания объекта-прокси.
Занятно. А почему бы не использовать ключевое слово object? Тогда получатся те же записи, но с "приклеенными" к ним методами. Кроме того, в некоторых случаях полезным бывает наследовать записи друг от друга — для record это невозможно, а для object вполне. Если не делать виртуальных методов, то поведение будет в точности таким же.
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: освобождение памяти при работе с динамическими объект
От: Вячеслав Ермолаев  
Дата: 10.09.03 11:37
Оценка:
Здравствуйте, Prinzip, Вы писали:

Проверяем
class TComponent2: public TComponent
{
private:
     char* m_Mem ;
public:
    __fastcall TComponent2(TComponent* Owner):TComponent(Owner),m_Mem(new char[1000]){}
    __fastcall ~TComponent2(){delete [] m_Mem;}
};
vector<TComponent2*> allA;


void __fastcall TForm2::Button1Click(TObject *Sender)
{
  static int i = 0;

  TComponent2 *A = new TComponent2(NULL);
  A->Name = "Component2" + AnsiString(i++);
  allA.push_back(A);

}
//---------------------------------------------------------------------------
void __fastcall TForm2::Button2Click(TObject *Sender)
{
 for(unsigned int i=0; i<allA.size();i++)
   delete allA[i];
 allA.clear();
 //vector<TComponent2*> allA1;
 //allA.swap(allA1);

}


Если не нажать Button2 перед выходом программы, то CodeGuard фиксирует утечку памяти.Если Button2 была нажата, утечка не фиксируется.
Какие проблемы?
С уважением, Вячеслав Ермолаев
Re[5]: освобождение памяти при работе с динамическими объект
От: Prinzip  
Дата: 10.09.03 11:45
Оценка:
Здравствуйте, Вячеслав Ермолаев, Вы писали:

ВЕ>Если не нажать Button2 перед выходом программы, то CodeGuard фиксирует утечку памяти.Если Button2 была нажата, утечка не фиксируется.

ВЕ>Какие проблемы?

Так точно! Имеено так всё и есть, только у меня чуть др компонет. Так вот когда мы создаём компонент и он появляется на форме, а потом удаляем его, то на форме он продолжает висеть и отвечать на события! Вот!

А компонент типа того:

class TMyComponent : public TComponent
{
.......
TGroupBox *GrBox;
TMemo     *Memo;
........
}
Re[6]: освобождение памяти при работе с динамическими объект
От: Вячеслав Ермолаев  
Дата: 10.09.03 11:56
Оценка:
Здравствуйте, Prinzip, Вы писали:

P>Здравствуйте, Вячеслав Ермолаев, Вы писали:


ВЕ>>Если не нажать Button2 перед выходом программы, то CodeGuard фиксирует утечку памяти.Если Button2 была нажата, утечка не фиксируется.

ВЕ>>Какие проблемы?

P>Так точно! Имеено так всё и есть, только у меня чуть др компонет. Так вот когда мы создаём компонент и он появляется на форме, а потом удаляем его, то на форме он продолжает висеть и отвечать на события! Вот!


P>А компонент типа того:


P>
P>class TMyComponent : public TComponent
P>{
P>.......
P>TGroupBox *GrBox;
P>TMemo     *Memo;
P>........
P>}
P>


T.e видны эти TGroupBox и TMemo?
А код конструктора (или тот участок, где GrBox и Memo создаются) и деструктора компонента можно?
С уважением, Вячеслав Ермолаев
Re[7]: освобождение памяти при работе с динамическими объект
От: Prinzip  
Дата: 10.09.03 12:10
Оценка:
Здравствуйте, Вячеслав Ермолаев, Вы писали:

ВЕ>T.e видны эти TGroupBox и TMemo?

ВЕ>А код конструктора (или тот участок, где GrBox и Memo создаются) и деструктора компонента можно?

Ох, сорри, в предыдущий раз не тот класс показщал не тот класс показал:

class TMyComponent2 : public TGroupBox
{
private:
TMemo     *Memo;
public:
__fastcall TMyComponent2::TMyComponent2(TComponent* Owner)
               : TGroupBox(Owner)
{
   TMemo *iMemo = new TMemo(this);
   iMemo->Parent=this;
   Memo=iMemo;
}
   __fastcall ~TMyComponent2(){delete Memo;};
};


При вызове
 delete allA[i];
деструктор не вызывается!!!!

Буду рад, если укажешь на мою ошибку.
Re[2]: освобождение памяти при работе с динамическими объект
От: vedmalex Россия  
Дата: 10.09.03 12:52
Оценка:
Здравствуйте, Mystic, Вы писали:

M>1) Менеджер памяти Delphi возвращает системе все свободный блоки, размер которых >= 15 Кб.

M>2) С другой стороны возможна (хотя и маловероята) фрагментация блоков.
M>3) Я бы рекомендовал в первую очередь оценить ситуацию с менеджером памяти Delphi. Для этого надо вызвать функцию GetHeapStatus, а нам сообщить значения элементов структуры THeapStatus. Во вском случае, "получается что структура размером 300 байт не удаляется вопреки ожиданиям" это только предположение.

ОК я понял. как доберусь до места попробую сделать.
Re[8]: освобождение памяти при работе с динамическими объект
От: Вячеслав Ермолаев  
Дата: 10.09.03 12:54
Оценка:
Здравствуйте, Prinzip, Вы писали:

P>Здравствуйте, Вячеслав Ермолаев, Вы писали:


ВЕ>>T.e видны эти TGroupBox и TMemo?

ВЕ>>А код конструктора (или тот участок, где GrBox и Memo создаются) и деструктора компонента можно?

P>Ох, сорри, в предыдущий раз не тот класс показщал не тот класс показал:



P>Буду рад, если укажешь на мою ошибку.

Был бы рад, но у меня этот код работает без ошибок
class TMyComponent2 : public TGroupBox
{
private:
TMemo     *Memo;
public:

__fastcall TMyComponent2::TMyComponent2(TComponent* Owner)
               : TGroupBox(Owner)
{
   TMemo *iMemo = new TMemo(this);
   iMemo->Parent=this;
   Memo=iMemo;
}
   __fastcall ~TMyComponent2(){delete Memo;};
};

vector<TMyComponent2*> allA;

void __fastcall TForm2::Button1Click(TObject *Sender)
{
  static int i = 0;
  static int nLeft = 0;
  static int nTop = 0;

  TMyComponent2 *A = new TMyComponent2(NULL);
  A->Left = nLeft;  nLeft += 10;
  A->Top = nTop;     nTop += 10;
  A->Parent = this;

  A->Name = "Component2" + AnsiString(i++);
  allA.push_back(A);

}

void __fastcall TForm2::Button2Click(TObject *Sender)
{
 for(unsigned int i=0; i<allA.size();i++)
   delete allA[i];
 allA.clear();
 //vector<TComponent2*> allA1;
 //allA.swap(allA1);

}

Деструктор вызывается, как ему и положено
С уважением, Вячеслав Ермолаев
Re[10]: освобождение памяти при работе с динамическими объек
От: Leonid Troyanovsky  
Дата: 10.09.03 13:46
Оценка:
Приветствую, Sinclair.

LT> Процедуры(глобальные) этого модуля принимают первым параметром указатель на обрабатываемую запись.

LT> Конечно, писать приходится немного больше, чем в случае объектов, но логика практически такая же.

> Занятно. А почему бы не использовать ключевое слово object? Тогда получатся те же записи, но с "приклеенными" к ним методами. Кроме того, в некоторых случаях полезным бывает наследовать записи друг от друга — для record это невозможно, а для object вполне. Если не делать виртуальных методов, то поведение будет в точности таким же.


Ну, автору вопроса хотелось большего контроля за памятью.
В случае с записями это реализуется неприлично просто, к тому же записи, все ж, проще объектов.
А наследование — это следующий шаг на пути к обобщениям, а уж там — никак без виртуальных методов

--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[11]: освобождение памяти при работе с динамическими объек
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.09.03 03:16
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

LT> Ну, автору вопроса хотелось большего контроля за памятью.

LT> В случае с записями это реализуется неприлично просто, к тому же записи, все ж, проще объектов.
Не-не-не. Управление памятью для object'ов — в точности такое же, как и для record'ов.
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[12]: освобождение памяти при работе с динамическими объек
От: Leonid Troyanovsky  
Дата: 11.09.03 08:08
Оценка:
Приветствую, Sinclair.

LT> В случае с записями это реализуется неприлично просто, к тому же записи, все ж, проще объектов.

> Не-не-не. Управление памятью для object'ов — в точности такое же, как и для record'ов.

Да, Бог с ней, с памятью.
Сам Object существует по забывчивости

От:Danny Thorpe (nomail@borland.com)
Заголовок:Re: Object types
Группы новостей:borland.public.delphi.language.objectpascal
Число:2003-08-27 10:06:19 PST

"Sriram A Nandakumar" <sriramn@icode.com> wrote in message
news:3f4cdd5b@newsgroups.borland.com...
> Thank you for the information and I shall not be using them.
>
> However, is there any place which gives the specifics on how they work with
> the list of issues that it poses — so that I can have a reasoning to avoid
> them. Also, KLib seems to be using it extensively..
>

Just to clarify: "old-style objects" means types declared using the TP7
syntax of "type TFoo = object..."

New-style refers to types declared using the Delphi syntax of "type TBar =
class...."

The Delphi compiler incorrectly allows some new class syntax on old object
types. Do not use properties on old-style objects, for example. The
compiler will accept the syntax but will not generate correct code.

The biggest incompatibility with old-style objects is that they are not
exception safe. If an exception escapes from the constructor of a class,
the compiler will make sure that the partially constructed instance will be
destroyed and freed. In the old-style objects, this does not happen. If an
exception escapes from the constructor of an old-style object, and you are
dynamically allocating the object, you are responsible for freeing the
partially constructed / failed instance.

Also, I'm not sure that the 32 bit Delphi compiler fully implements the
Fail() semantics associated with old-style object constructors. It probably
does, but I wouldn't be surprised if it does not.

Old-style object syntax has been deprecated since 1995 when Delphi 1.0 was
released. I don't know that we can ever get away with actually removing it
from the dcc32 compiler, but old-style syntax is definitely not supported by
new compiler work such as the Delphi for .NET compiler.

-Danny

--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[9]: освобождение памяти при работе с динамическими объект
От: Prinzip  
Дата: 11.09.03 12:18
Оценка:
Здравствуйте, Вячеслав Ермолаев, Вы писали:

ВЕ>Был бы рад, но у меня этот код работает без ошибок


Ты читер , а я ламер
Весь код изнасиловал — никак. У меня Builder 6.0 Build 10.157
Re[7]: освобождение памяти при работе с динамическими объект
От: vedmalex Россия  
Дата: 11.09.03 12:29
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

LT> Ну, тогда NewInstance/FreeInstance тебе в руки.

LT> По-крайней мере сам сможешь следить за своей памятью.
LT> Правда, другие объекты, входящие в поля будут по-прежнему управляться дельфийским менеджером.

Самое смешное что при ближайшем рассмотрении TObject
оказалось

constructor TObject.Create;
begin
end;

destructor TObject.Destroy;
begin
end;

procedure TObject.Free;
begin
  if Self <> nil then
    Destroy;
end;


т.е. предположение о том что данные вообще не удаляются верно
потому как в своих классах я вызывал базовый деструктор — который как видно из кода ни чего не освобождает.
Таким образом и объясняется что память освобождается после завершения программы.
Вот Блин.
Так что придется самому писать все ручками используя InitInstance/FreeInstance.
Хотя в Хелпе написано что все выполняется автоматически
т.е. InitInstance/FreeInstance
по всей видимости автоматически это после завершения программы.
Может я не прав?
Re: освобождение памяти при работе с динамическими объектами
От: Flamer Кипр http://users.livejournal.com/_flamer_/
Дата: 11.09.03 12:32
Оценка:
Здравствуйте, vedmalex, Вы писали:

[]

V>Вопрос каким образом заставить ОС или программу освобождать память после удаления объектов.


Если все удаляется корректно: SetProcessWorkingSetSize не поможет?


The SetProcessWorkingSetSize function sets the minimum and maximum working set sizes for a specified process.

The working set of a process is the set of memory pages currently visible to the process in physical RAM memory. These pages are resident and available for an application to use without triggering a page fault. The size of the working set of a process is specified in bytes. The minimum and maximum working set sizes affect the virtual memory paging behavior of a process.

BOOL SetProcessWorkingSetSize(

HANDLE hProcess, // open handle to the process of interest
DWORD dwMinimumWorkingSetSize, // specifies minimum working set size
DWORD dwMaximumWorkingSetSize // specifies maximum working set size
);

Re[10]: освобождение памяти при работе с динамическими объек
От: Вячеслав Ермолаев  
Дата: 11.09.03 12:37
Оценка:
Здравствуйте, Prinzip, Вы писали:

P>Здравствуйте, Вячеслав Ермолаев, Вы писали:


ВЕ>>Был бы рад, но у меня этот код работает без ошибок


P>Ты читер , а я ламер

P>Весь код изнасиловал — никак. У меня Builder 6.0 Build 10.157

У меня Builder 6.0 Build 10.166
Но сомневаюсь, что бы это играло роль. Это, так сказать, базис.
Может проектик пришлешь?
С уважением, Вячеслав Ермолаев
Re[9]: освобождение памяти при работе с динамическими объект
От: Prinzip  
Дата: 11.09.03 12:38
Оценка:
Здравствуйте, Вячеслав Ермолаев, Вы писали:

Сорри я точно ламер:

void __fastcall TForm1::Button1Click(TObject *Sender)
{
TMyComponent2 *A = new TMyComponent2(NULL);
A->PopupMenu=PopupMenu1;
A->Height=100;
A->Width=100;
A->Tag=allA.size();
A->Left=10*(allA.size()+1);
A->Top=10*(allA.size()+1);
A->Name = "Component2" + AnsiString(allA.size()+1);
A->Parent=this;
A->Refresh();
allA.push_back();
}
Re[8]: освобождение памяти при работе с динамическими объект
От: Leonid Troyanovsky  
Дата: 11.09.03 12:53
Оценка:
Здравствуйте, vedmalex, Вы писали:

V>т.е. предположение о том что данные вообще не удаляются верно

V> потому как в своих классах я вызывал базовый деструктор — который как видно из кода ни чего не освобождает.

Т.е., ты не перекрыл Destroy, а освобождал Free?
Тогда твой деструктор и не срабатывал.
А чего, в отладчике этого рассмотреть не удалось?

V>Так что придется самому писать все ручками используя InitInstance/FreeInstance.


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

--
С уважением, LVT.
--
С уважением, LVT
Re[8]: освобождение памяти при работе с динамическими объект
От: Mystic Украина http://mystic2000.newmail.ru
Дата: 11.09.03 13:26
Оценка:
Здравствуйте, vedmalex, Вы писали:

V>Здравствуйте, Leonid Troyanovsky, Вы писали:


V>т.е. предположение о том что данные вообще не удаляются верно


Неверно.

var
  Obj: TObject;

begin
  WriteLn('AllocMemCount=', AllocMemCount, ' AllocMemSize=', AllocMemSize);
  Obj := TObject.Create;
  try
    WriteLn('AllocMemCount=', AllocMemCount, ' AllocMemSize=', AllocMemSize);
  finally
    Obj.Free;
  end;
  WriteLn('AllocMemCount=', AllocMemCount, ' AllocMemSize=', AllocMemSize);
  ReadLn;
end.


Дает:

AllocMemCount=77 AllocMemSize=1696
AllocMemCount=78 AllocMemSize=1704
AllocMemCount=77 AllocMemSize=1696


На самом деле чать функциональности скрыта в функциях

function _ClassCreate(AClass: TClass; Alloc: Boolean): TObject;
procedure _ClassDestroy(Instance: TObject);

которые вызываются автоматически при создании/удалении класса. Последняя процедура имеет вид:

procedure _ClassDestroy(Instance: TObject);
begin
  Instance.FreeInstance;
end;
Re[9]: освобождение памяти при работе с динамическими объект
От: Аноним  
Дата: 12.09.03 09:20
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:

LT> Т.е., ты не перекрыл Destroy, а освобождал Free?

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

destructor TDBQuery.Destroy;
var I:Integer;
HS:THeapStatus;
begin
if Assigned(FSelectClause) then
  FSelectClause.Free;
if Assigned(FWhereClause) then
  FWhereClause.Free;
  inherited destroy;
end;

destructor TDBWhereClause.Destroy;
begin
if Assigned(fTableList) then
  fTableList.Free;
if Assigned(fIndexList) then
fIndexList.Free;
  inherited Destroy;
end;

destructor TDBSelectClause.Destroy;
begin
if Assigned(fTableList) then
  fTableList.Free;
  inherited Destroy;
end;


а inherited Destroy в TDBQuery TObject.destroy
ну а в списках конечный вариант так же TObject.destroy
т.е. я о чем говорю — что придется самому управлять созданием
ну это хоть разбивает ту иллюзию что Delphi сам все рулит.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.