Здравствуйте, vedmalex, Вы писали:
V>Проблема заключается в следующем: V>Есть прога — модель СМО(ситсемы массового обслуживания) а конкретно модель СУБД. V>Все прекрасно работает без исключений и прочее. V>Моделирование: все элементы модели Объкты дерево. Динамически путем копирования создаются структуры типа запросы, которые далее удаляются в одном из блоков. Удаляется все тоже по правилам по всем. НО полсе создания примерно 450 000 штук запросов(объектов типа запрос) размер ОП выделяемой программой увеличивается на 120 М получается что структура размером 300 байт не удаляется вопреки ожиданиям. После завершения программы размер свободной ОП восстанавливается. V>Т.е. я понимаю что после вызова деструктора память не освобождаемтся. V>Я так понимаю, все объекты типа наслеуемые от TObject являются динамичесмкими — размещаются в "КУЧЕ". Если не так поправьте меня.
V>Вопрос каким образом заставить ОС или программу освобождать память после удаления объектов.
1) Менеджер памяти Delphi возвращает системе все свободный блоки, размер которых >= 15 Кб.
2) С другой стороны возможна (хотя и маловероята) фрагментация блоков.
3) Я бы рекомендовал в первую очередь оценить ситуацию с менеджером памяти Delphi. Для этого надо вызвать функцию GetHeapStatus, а нам сообщить значения элементов структуры THeapStatus. Во вском случае, "получается что структура размером 300 байт не удаляется вопреки ожиданиям" это только предположение.
Re[3]: освобождение памяти при работе с динамическими объект
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> Процедуры(глобальные) этого модуля принимают первым параметром указатель на обрабатываемую запись. LT> Конечно, писать приходится немного больше, чем в случае объектов, но логика практически такая же. LT> Также это облегчает создание истинно объектной оболочки (если она вдруг потребуется), путем написания объекта-прокси.
Занятно. А почему бы не использовать ключевое слово object? Тогда получатся те же записи, но с "приклеенными" к ним методами. Кроме того, в некоторых случаях полезным бывает наследовать записи друг от друга — для record это невозможно, а для object вполне. Если не делать виртуальных методов, то поведение будет в точности таким же.
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: освобождение памяти при работе с динамическими объект
Здравствуйте, Вячеслав Ермолаев, Вы писали:
ВЕ>Если не нажать Button2 перед выходом программы, то CodeGuard фиксирует утечку памяти.Если Button2 была нажата, утечка не фиксируется. ВЕ>Какие проблемы?
Так точно! Имеено так всё и есть, только у меня чуть др компонет. Так вот когда мы создаём компонент и он появляется на форме, а потом удаляем его, то на форме он продолжает висеть и отвечать на события! Вот!
А компонент типа того:
class TMyComponent : public TComponent
{
.......
TGroupBox *GrBox;
TMemo *Memo;
........
}
Re[6]: освобождение памяти при работе с динамическими объект
Здравствуйте, Prinzip, Вы писали:
P>Здравствуйте, Вячеслав Ермолаев, Вы писали:
ВЕ>>Если не нажать Button2 перед выходом программы, то CodeGuard фиксирует утечку памяти.Если Button2 была нажата, утечка не фиксируется. ВЕ>>Какие проблемы?
P>Так точно! Имеено так всё и есть, только у меня чуть др компонет. Так вот когда мы создаём компонент и он появляется на форме, а потом удаляем его, то на форме он продолжает висеть и отвечать на события! Вот!
P>А компонент типа того:
P>
Здравствуйте, Вячеслав Ермолаев, Вы писали:
ВЕ>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]: освобождение памяти при работе с динамическими объект
Здравствуйте, Mystic, Вы писали:
M>1) Менеджер памяти Delphi возвращает системе все свободный блоки, размер которых >= 15 Кб. M>2) С другой стороны возможна (хотя и маловероята) фрагментация блоков. M>3) Я бы рекомендовал в первую очередь оценить ситуацию с менеджером памяти Delphi. Для этого надо вызвать функцию GetHeapStatus, а нам сообщить значения элементов структуры THeapStatus. Во вском случае, "получается что структура размером 300 байт не удаляется вопреки ожиданиям" это только предположение.
ОК я понял. как доберусь до места попробую сделать.
Re[8]: освобождение памяти при работе с динамическими объект
Здравствуйте, Prinzip, Вы писали:
P>Здравствуйте, Вячеслав Ермолаев, Вы писали:
ВЕ>>T.e видны эти TGroupBox и TMemo? ВЕ>>А код конструктора (или тот участок, где GrBox и Memo создаются) и деструктора компонента можно?
P>Ох, сорри, в предыдущий раз не тот класс показщал не тот класс показал:
P>Буду рад, если укажешь на мою ошибку.
Был бы рад, но у меня этот код работает без ошибок
Приветствую, Sinclair.
LT> Процедуры(глобальные) этого модуля принимают первым параметром указатель на обрабатываемую запись. LT> Конечно, писать приходится немного больше, чем в случае объектов, но логика практически такая же.
> Занятно. А почему бы не использовать ключевое слово object? Тогда получатся те же записи, но с "приклеенными" к ним методами. Кроме того, в некоторых случаях полезным бывает наследовать записи друг от друга — для record это невозможно, а для object вполне. Если не делать виртуальных методов, то поведение будет в точности таким же.
Ну, автору вопроса хотелось большего контроля за памятью.
В случае с записями это реализуется неприлично просто, к тому же записи, все ж, проще объектов.
А наследование — это следующий шаг на пути к обобщениям, а уж там — никак без виртуальных методов
--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[11]: освобождение памяти при работе с динамическими объек
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> Ну, автору вопроса хотелось большего контроля за памятью. LT> В случае с записями это реализуется неприлично просто, к тому же записи, все ж, проще объектов.
Не-не-не. Управление памятью для object'ов — в точности такое же, как и для record'ов.
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[12]: освобождение памяти при работе с динамическими объек
Приветствую, Sinclair.
LT> В случае с записями это реализуется неприлично просто, к тому же записи, все ж, проще объектов. > Не-не-не. Управление памятью для object'ов — в точности такое же, как и для record'ов.
Да, Бог с ней, с памятью.
Сам Object существует по забывчивости
"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]: освобождение памяти при работе с динамическими объект
Здравствуйте, 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: освобождение памяти при работе с динамическими объектами
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]: освобождение памяти при работе с динамическими объек
Здравствуйте, Prinzip, Вы писали:
P>Здравствуйте, Вячеслав Ермолаев, Вы писали:
ВЕ>>Был бы рад, но у меня этот код работает без ошибок
P>Ты читер , а я ламер P>Весь код изнасиловал — никак. У меня Builder 6.0 Build 10.157
У меня Builder 6.0 Build 10.166
Но сомневаюсь, что бы это играло роль. Это, так сказать, базис.
Может проектик пришлешь?
С уважением, Вячеслав Ермолаев
Re[9]: освобождение памяти при работе с динамическими объект
Здравствуйте, vedmalex, Вы писали:
V>т.е. предположение о том что данные вообще не удаляются верно V> потому как в своих классах я вызывал базовый деструктор — который как видно из кода ни чего не освобождает.
Т.е., ты не перекрыл Destroy, а освобождал Free?
Тогда твой деструктор и не срабатывал.
А чего, в отладчике этого рассмотреть не удалось?
V>Так что придется самому писать все ручками используя InitInstance/FreeInstance.
Если ты не хочешь сам выделять память, то этого ничего не нужно,
оно делается автоматом, при вызове конструктора и деструктора.
--
С уважением, LVT.
--
С уважением, LVT
Re[8]: освобождение памяти при работе с динамическими объект
На самом деле чать функциональности скрыта в функциях
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 сам все рулит.