Проблема заключается в следующем:
Есть прога — модель СМО(ситсемы массового обслуживания) а конкретно модель СУБД.
Все прекрасно работает без исключений и прочее.
Моделирование: все элементы модели Объкты дерево. Динамически путем копирования создаются структуры типа запросы, которые далее удаляются в одном из блоков. Удаляется все тоже по правилам по всем. НО полсе создания примерно 450 000 штук запросов(объектов типа запрос) размер ОП выделяемой программой увеличивается на 120 М получается что структура размером 300 байт не удаляется вопреки ожиданиям. После завершения программы размер свободной ОП восстанавливается.
Т.е. я понимаю что после вызова деструктора память не освобождаемтся.
Я так понимаю, все объекты типа наслеуемые от TObject являются динамичесмкими — размещаются в "КУЧЕ". Если не так поправьте меня.
Вопрос каким образом заставить ОС или программу освобождать память после удаления объектов.
Re: освобождение памяти при работе с динамическими объектами
От:
Аноним
Дата:
05.09.03 12:29
Оценка:
Здравствуйте, vedmalex, Вы писали:
V>Проблема заключается в следующем: V>Есть прога — модель СМО(ситсемы массового обслуживания) а конкретно модель СУБД. V>Все прекрасно работает без исключений и прочее. V>Моделирование: все элементы модели Объкты дерево. Динамически путем копирования создаются структуры типа запросы, которые далее удаляются в одном из блоков. Удаляется все тоже по правилам по всем. НО полсе создания примерно 450 000 штук запросов(объектов типа запрос) размер ОП выделяемой программой увеличивается на 120 М получается что структура размером 300 байт не удаляется вопреки ожиданиям. После завершения программы размер свободной ОП восстанавливается. V>Т.е. я понимаю что после вызова деструктора память не освобождаемтся. V>Я так понимаю, все объекты типа наслеуемые от TObject являются динамичесмкими — размещаются в "КУЧЕ". Если не так поправьте меня.
V>Вопрос каким образом заставить ОС или программу освобождать память после удаления объектов.
Всё правильно, они именно там и размещаются. Если у тебя объекты одного типа и их много, как раз как в твоём случае, то логичнее
использовать (и самому в этом случае управлять) виртуальную
память — это функции VirtualAlloc(...), VirtualFree. С ними по крайней мере ты сам резервируешь регион, сам коммитишь память и сам же её
возвращаешь системе и освобждаешь регион. (Возьми книжку Дж. Рихтер "Создание эффективных Win32 приложений" там про
это всё отлично расписано).
Удачи!
Re: освобождение памяти при работе с динамическими объектами
От:
Аноним
Дата:
05.09.03 12:30
Оценка:
>Я так понимаю, все объекты типа наслеуемые от TObject являются динамичесмкими — размещаются в "КУЧЕ". Если не так >поправьте меня.
Смотря что понимать под кучей.
Если стандартную виндовскую кучу — то нет.
У Борланда свой менеджер памяти, который получает память непосредственно у
системы через VirtualAlloc и сам решает, когда возвратить её системе.
Чесно говоря, я слабо представляю, как можно заставить стандартный менеджер форсировать это действие,
кроме как использовать другой менеджер.
(Или перекрыть InitInstance/FreeInstance для запроса).
А структуры там ещё откуда — это место я не понял.
Re[2]: освобождение памяти при работе с динамическими объект
Здравствуйте, Аноним, Вы писали:
А>Всё правильно, они именно там и размещаются. Если у тебя объекты одного типа и их много, как раз как в твоём случае, то логичнее А>использовать (и самому в этом случае управлять) виртуальную А>память — это функции VirtualAlloc(...), VirtualFree. С ними по крайней мере ты сам резервируешь регион, сам коммитишь память и сам же её А>возвращаешь системе и освобждаешь регион. (Возьми книжку Дж. Рихтер "Создание эффективных Win32 приложений" там про А>это всё отлично расписано).
А>Удачи!
Спасибо, в общем понятно каким образом дейсвтовать.
Ок Буду искать варианты.
Re[2]: освобождение памяти при работе с динамическими объект
Здравствуйте, Аноним, Вы писали:
А>А структуры там ещё откуда — это место я не понял.
я честно говоря сам не понял, просто выделяется память и все под динамический объект типа class,
да я почитал доки — память освобождается автоматически после удаления объекта — вызова методов destroy/free.
т.е. я понял это просто несовершенство разработки.
Re: освобождение памяти при работе с динамическими объектами
Здравствуйте, vedmalex, Вы писали: V>Есть прога — модель СМО(ситсемы массового обслуживания) а конкретно модель СУБД. V>Все прекрасно работает без исключений и прочее. V>Моделирование: все элементы модели Объкты дерево. Динамически путем копирования создаются структуры типа запросы, которые далее удаляются в одном из блоков. Удаляется все тоже по правилам по всем. НО полсе создания примерно 450 000 штук запросов(объектов типа запрос) размер ОП выделяемой программой увеличивается на 120 М получается что структура размером 300 байт не удаляется вопреки ожиданиям. После завершения программы размер свободной ОП восстанавливается. V>Т.е. я понимаю что после вызова деструктора память не освобождаемтся.
Re[2]: освобождение памяти при работе с динамическими объект
От:
Аноним
Дата:
08.09.03 10:37
Оценка:
Здравствуйте, ArtDenis, Вы писали: AD>А что BoundsChecker говорит?
просто на Pascal кажется нет такого.
просто проблемма состоит в том что базовые классы моей модели написаны на Object Pascal
Re[3]: освобождение памяти при работе с динамическими объект
От:
Аноним
Дата:
08.09.03 10:41
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> А что, собс-но, ты ищешь?
Решение проблеммы, Освобождения памяти.
Я просто думаю может что еще не доделал или переборщил,
но вроде бы с сотового взгляда все правильно, все объекты освобождаю ни где ошибок нет, исключений тоже. а вот память освобождается только после выхода из программы.
Re[4]: освобождение памяти при работе с динамическими объект
Здравствуйте, Аноним, Вы писали:
LT> А что, собс-но, ты ищешь?
А>Решение проблеммы, Освобождения памяти. А>Я просто думаю может что еще не доделал или переборщил, А>но вроде бы с сотового взгляда все правильно, все объекты освобождаю ни где ошибок нет, исключений тоже. а вот память освобождается только после выхода из программы.
Во-первых, непонятно как ты оцениваешь размер свободной памяти.
Если ты смотришь из Task Manager(NT-XP) — это не совсем то, чем кажется. (Если приложение с формой, то попробуй, например, свернуть и развернуть его).
Оценивать же свое приложение лучше с помощью Performarnce Monitor, для объекта Process (своего приложения).
Ну, а по существу — 450 тыс. объектов — если они все время создаются и
разрушаются — на мой взгляд — перебор. Лучше попытаться описывать _это_ не
объектами а записями, т.е. TMyQuery = record .. end;
Память же для такого массива не грех распределить самому, т.е.
VirtualAlloc. Тогда и за ее освобождение (VirtualFree) пенять придется
только на себя.
Если же нужно все это хозяйство хранить (на диске) то лучше сразу
смотреть в сторону CreateFileMapping — MapViewOfFile.
--
С уважением, LVT.
--
С уважением, LVT
Re[5]: освобождение памяти при работе с динамическими объект
Здравствуйте, Leonid Troyanovsky, Вы писали: LT> Во-первых, непонятно как ты оцениваешь размер свободной памяти. LT> Если ты смотришь из Task Manager(NT-XP) — это не совсем то, чем кажется. (Если приложение с формой, то попробуй, например, свернуть и развернуть его). LT> Оценивать же свое приложение лучше с помощью Performarnce Monitor, для объекта Process (своего приложения).
LT> Ну, а по существу — 450 тыс. объектов — если они все время создаются и LT> разрушаются — на мой взгляд — перебор. Лучше попытаться описывать _это_ не LT> объектами а записями, т.е. TMyQuery = record .. end; LT> Память же для такого массива не грех распределить самому, т.е. LT> VirtualAlloc. Тогда и за ее освобождение (VirtualFree) пенять придется LT> только на себя. LT> Если же нужно все это хозяйство хранить (на диске) то лучше сразу LT> смотреть в сторону CreateFileMapping — MapViewOfFile.
Да на самао деле по таск менеджеру но только рост оперативки на столько силен что ни какие свертываения окон не помогают.
а 450 тысяч объектов за моджельное время около 2 часов, по машинному около минуты
нет все не совсем так, запрос это класс по определению, содержит кучу функций и всякой лабуды типа
список селект полей
список полей в условии и мне проще написать класс один раз а затем выполняя функцию
copy этого класса клонировать эти запросы, потому как они на самом деле стандартные или входят в состав стандартных транзакций.
это уже вопрос проектирования,
А запросы они уничтожаются не сразу а по прохождению определенных блоков
В общем так проще чем использовать записи, к тому же есть возможность расширения.
просто хочется красиво сделать
Re[6]: освобождение памяти при работе с динамическими объект
Приветствую, vedmalex.
> нет все не совсем так, запрос это класс по определению, содержит кучу функций и всякой лабуды типа > список селект полей > список полей в условии и мне проще написать класс один раз а затем выполняя функцию > copy этого класса клонировать эти запросы, потому как они на самом деле стандартные или входят в состав стандартных транзакций. > это уже вопрос проектирования,
Ну, тогда NewInstance/FreeInstance тебе в руки.
По-крайней мере сам сможешь следить за своей памятью.
Правда, другие объекты, входящие в поля будут по-прежнему управляться дельфийским менеджером.
--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[7]: освобождение памяти при работе с динамическими объект
От:
Аноним
Дата:
10.09.03 05:26
Оценка:
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> Ну, тогда NewInstance/FreeInstance тебе в руки. LT> По-крайней мере сам сможешь следить за своей памятью. LT> Правда, другие объекты, входящие в поля будут по-прежнему управляться дельфийским менеджером.
ОК.
Но я так же подумаю на счет размещения в записи,
по крайней мере можно создать объект который будет работать с запросами типа рекорд.
Спасибо за наметку
Re[7]: освобождение памяти при работе с динамическими объект
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> Правда, другие объекты, входящие в поля будут по-прежнему управляться дельфийским менеджером.
Ну, его тоже заменить не проблема. Можно посмотреть исходник ShareMem для примера.
... << RSDN@Home 1.1 beta 2 >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[8]: освобождение памяти при работе с динамическими объект
Приветствую, Sinclair.
LT> Правда, другие объекты, входящие в поля будут по-прежнему управляться дельфийским менеджером. > Ну, его тоже заменить не проблема. Можно посмотреть исходник ShareMem для примера.
Да, конечно. Правда, на практике с таким не сталкивался, т.к. мне сложно предложить нечто более эффективное, скажем, для строк или вариантов Скорее, я мог бы столкнуться с вариантом замены библиотечного менеджера на таковой из приложения, но и это, слава Богу, меня миновало.
--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[8]: освобождение памяти при работе с динамическими объект
Приветствую.
> Но я так же подумаю на счет размещения в записи, > по крайней мере можно создать объект который будет работать с запросами типа рекорд.
Удобно размышлять над записями, как над объектами, разместив методы работы с ними в отдельном модуле.
Процедуры(глобальные) этого модуля принимают первым параметром указатель на обрабатываемую запись.
Конечно, писать приходится немного больше, чем в случае объектов, но логика практически такая же.
Также это облегчает создание истинно объектной оболочки (если она вдруг потребуется), путем написания объекта-прокси.
--
С уважением, LVT.
Posted via RSDN NNTP Server 1.7 beta
--
С уважением, LVT
Re[9]: освобождение памяти при работе с динамическими объект
Здравствуйте, Leonid Troyanovsky, Вы писали:
LT> Процедуры(глобальные) этого модуля принимают первым параметром указатель на обрабатываемую запись. LT> Конечно, писать приходится немного больше, чем в случае объектов, но логика практически такая же. LT> Также это облегчает создание истинно объектной оболочки (если она вдруг потребуется), путем написания объекта-прокси.
ОК.
Что то похожее я и собираюсь сделать.
Спасибо.
Re: освобождение памяти при работе с динамическими объектами
У меня та же проблема.
А как правильно удалять свой компонент? Я его создаю на форме, удаляю, а он всё висит и на все события реагирует. Создаю new, удаляю delete.
Re[2]: освобождение памяти при работе с динамическими объект
Здравствуйте, Prinzip, Вы писали:
P>У меня та же проблема. P>А как правильно удалять свой компонент? Я его создаю на форме, удаляю, а он всё висит и на все события реагирует. Создаю new, удаляю delete.
Очень сранно. Никогда с подобным не сталкивался. По подробнее можно?
С уважением, Вячеслав Ермолаев
Re: освобождение памяти при работе с динамическими объектами
Здравствуйте, 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 сам все рулит.
Re[10]: освобождение памяти при работе с динамическими объек
Здравствуйте, Аноним, Вы писали:
А>Нет декструкторы я все перекрывал, все как положено. А>просто делалось так освободил свое вызови парент destroy.
Чего-то я не уяснил, как и что тебе удалось
А>[pascal] А>destructor TDBQuery.Destroy; А>var I:Integer; А>HS:THeapStatus; А>begin А>if Assigned(FSelectClause) then А> FSelectClause.Free; А>if Assigned(FWhereClause) then А> FWhereClause.Free; А> inherited destroy; А>end;
Ты, уж если приводишь части кода, то привел бы минимально
достаточный для понимания (компиляции) пример, который
любой любознательный человек мог бы воспроизвести у себя.
Глядишь, обсуждение стало бы более плодотворным
Ну ты же видел реализацию Free — там уже есть if Assigned(..),
т.е. просто fTableList.Free;
А>а inherited Destroy в TDBQuery TObject.destroy А>ну а в списках конечный вариант так же TObject.destroy А>т.е. я о чем говорю — что придется самому управлять созданием А>ну это хоть разбивает ту иллюзию что Delphi сам все рулит.
Так в чем у тебя сомнения? Что List{as TList}.Free не освобождает память?
IMHO, по крайней мере, с ним все нормально.
Другое дело, если ты например, заполнил его ссылками на объекты — то они будут жить до своего Free.
Примерно тоже можно сказать про объектные ссылки в полях твоего объекта (если они, например, бесхозные компоненты)
--
С уважением, LVT.
--
С уважением, LVT
Re[11]: освобождение памяти при работе с динамическими объек
Ок, Привожу часть кода.
объект Объект Lists — Реулизует двунаправленный список
type
TElement = class (TObject)
public
Next: TElement;
Prev: TElement;
constructor Create;
function Copy: TElement; virtual;
function ViewState:string;virtual;
destructor Destroy; override;
end;
TLists = class (TElement)
protected
FCount: Word;
FCurrent: TElement;
Head: TElement;
Tail: TElement;
function GetEmpty: Boolean;
public
function Consist:Boolean;
constructor Create;
destructor Destroy; override;
procedure AppendToBottom(R: TElement);
procedure AppendToTop(R: TElement);
function Back(var R): Boolean;
procedure Exclude(R : TElement);
function ExtractFromTop: TElement;
function ExtractFromBottom:TElement;
function FForward(var R): Boolean;
function ReWind(var R): Boolean;
function Skip(var R): Boolean;
property Count: Word read FCount;
property Current: TElement read FCurrent;
property Empty: Boolean read GetEmpty;
end;
Деструктор выфглядит следующим образом:
destructor TLists.Destroy;
var
R: TElement;
begin
if FCount > 0 then
while Assigned(Tail) do
begin
R:=Tail.Next;
Tail.Free;
Tail:=R;
end;
FCount:=0;
inherited Destroy;
end;
destructor TElement.Destroy;
begin
inherited Destroy;
end;
только часть пока что.
Re[12]: освобождение памяти при работе с динамическими объек
Здравствуйте, vedmalex, Вы писали:
V>Ок, Привожу часть кода.
V> TLists = class (TElement)
Зачем TLists наследовать от TElement, а не от TObject?
Кстати, мы, вроде бы, договорились приводить такой код,
который может откомпилировать _любой_ без особых напрягов.
V>Деструктор выфглядит следующим образом:
V>destructor TLists.Destroy; V>var V> R: TElement; V>begin V>if FCount > 0 then V> while Assigned(Tail) do V> begin V> R:=Tail.Next; V> Tail.Free;
Мне, конечно, трудно судить, что есть Tail, но, судя по именам,
использовать следует Prev, а не Next.V> Tail:=R;
V>только часть пока что.
Именно часть, именно. Никто и не не будет читать случайные обрывки
твоего проекта. Чем больше ты времени потратишь на подготовку
понятного другим кода, тем больше вероятность получить правильный ответ.
Пока же у меня один вопрос, почему ты не использовал вполне обычный TList.
Я не думаю, что он не уложился в те самые минуты на 450 тыс.
Ну и про использование объектов, а не записей пока не видел резонов.
--
С уважением, LVT.
--
С уважением, LVT
Re[13]: освобождение памяти при работе с динамическими объек
От:
Аноним
Дата:
15.09.03 07:11
Оценка:
Здравствуйте, Leonid Troyanovsky
ОК,
Я сделаю, как приеду из командировки,
А по поводу того что список не работает
эти классы работают и это ДеФакто.
почему наследует от TElement — потому что список так же может быть элементом списка
Почему не использовал Tlist — потому как базовые классы
для модели разработаны до меня, но я уже склоняюсь к тому что все переписать все базовые классы под себя а может часть их удалить.
Могу если есть желание переславть полные исходники, все проги.
С Уважением , VEDMALEX.
Re[14]: освобождение памяти при работе с динамическими объек
Здравствуйте, Аноним, Вы писали:
А>почему наследует от TElement — потому что список так же может быть элементом списка
Списку нет нужды быть элементом списка, т.к. один список может содержать все ссылки, достаточно снабдить каждый эго элемент идентификатором группы.
Если нужен быстрый доступ к отдельным группам, то можно сделать на основе TList индекс, который будет содержать (отсортированный) список группы.
Можно даже снабдить этот TList методом Find (бинарного поиска), для быстрого позиционирования на ближайший (по критерию) элемент.
А>Почему не использовал Tlist — потому как базовые классы А>для модели разработаны до меня, но я уже склоняюсь к тому что все переписать все базовые классы под себя а может часть их удалить.
Возможно, что лучший способ разобраться — сделать все самому
А>Могу если есть желание переславть полные исходники, все проги.
Спасибо, конечно, за доверие, однако желания такого не испытываю.
Лучше десять простых вопросов, чем один сложный.
--
С уважением, LVT.
--
С уважением, LVT
Re: освобождение памяти при работе с динамическими объектами
Привет Всем.
Вот я и добрался до рабочего места.
Вроде нашел проблемму она заключается в том что я копирую объекты своей фнкцией.
т.е. в процессе роботы вызываю процедуру COPY.
ошибку нашел с помощью memchck.
кто нить может мне внятно объяснить почем так и как сделать так что бы было нормально
и вообще какие есть методу копирования клонирования объектов.
Вот тут набросал код который генерить исключение.
program Project1;
{$APPTYPE CONSOLE}uses
SysUtils,
MemCheck in'MemCheck.pas';
type
TElement = class(TObject)
protected
Next:TElement;
Prev:TElement;
Name : string;
constructor Create(aName :string);
function Copy:TClass;virtual;
procedure CopyVar(var C);virtual;
end;
RefTClass = Class of Telement;
TElemDesc = class(TElement)
HW_Time:Extended;
CPU_Time:Extended;
constructor Create(aName:string ;aHW_Time,aCPU_Time:Extended);
function Copy:TClass;override;
procedure CopyVar(var C);override;
end;
constructor TElement.Create(aName :string);
begin
inherited Create;
Name:=aName;
end;
function TElement.Copy:TClass;
begin
Result := TClass(TElement.Create(Name));
end;
procedure Telement.CopyVar(var C);
var R:TElement absolute C;
begin
r:=TElement.Create(NAme);
end;
constructor TElemDEsc.Create(aName:string ;aHW_Time,aCPU_Time:Extended);
begin
inherited Create(aName);
HW_Time:=aHW_Time;
CPU_Time:=aCPU_Time;
end;
function TElemDEsc.Copy:TClass;
begin
Result:=TClass(Create(Name,HW_Time,CPU_Time));
end;
procedure TElemDesc.CopyVar(var C);
var R:TElemDEsc absolute C;
begin
R:=Create(Name,HW_Time,CPU_Time);
end;
var
i:Integer;
ElArr:array[0..9] of TElement;
DEscArr:array[0..9] of TElemDesc;
El:TElement;
DEsc:TElemDesc;
begin//memchk;
Writeln('Creating Base');
//setLength(ElArr,10);
El:=TElement.Create(Format('Elem %D',[1]));
for i:=0 to 9 do
begin
ElArr[i]:=El.Copy;
//El.CopyVar(ElArr[i]);
ElArr[i].Name:=Format('Elem %D',[1]);
end;
Writeln('Creating Descendant');
//setLength(DEscArr,10);
Desc:=TElemDesc.Create(Format('DEsc %D',[1]),100,100);
for i:=0 to 9 do
begin
DescArr[i]:=TElemDEsc(DEsc.Copy);
//desc.CopyVar(DEscArr[i]);
DEscArr[i]:=TElemDesc.Create(Format('DEsc %D',[i]),100,100);
DescArr[i].Name:=Format('DEsc %D',[1]);
end;
writeln('Freeing Arrays Elements');
for i:=0 to 9 do
begin
ElArr[i].Free;
writeln(i);
end;
writeln('Freeing Arrays DEscendant');
for i:=0 to 9 do
begin
DescArr[i].Free; // при втором проходе ошибка
WriteLn(i);
end;
writeln('Freeing vars');
desc.Free;
El.Free;
readln;
end.
как видно пробовал два варианта, но ни один не работает можете убрать коментариии и закоментировать
Можете объяснить в чем трабла
... << RSDN@Home 1.1 beta 1 >>
Re[2]: освобождение памяти при работе с динамическими объект
Так вот небольшая неточность исправлена
в методе TElmDEsc.COPY конструктор вызывался без казания класса
теперь пример выглядит так:
program Project1;
{$APPTYPE CONSOLE}uses
SysUtils,classes,
MemCheck in'MemCheck.pas';
type
RefTelem = class of TElement;
TElement = class(TObject)
protected
Next:TElement;
Prev:TElement;
Name : string;
constructor Create(aName :string);
function Copy:TElement;virtual;
end;
TElemDesc = class(TElement)
public
HW_Time:LongWord;
CPU_Time:LongWord;
constructor Create(aName:string ;aHW_Time,aCPU_Time:LongWord);
function Copy:TElement;override;
end;
constructor TElement.Create(aName :string);
begin
inherited Create;
Name:=aName;
end;
function TElement.Copy:TElement;
begin
Result := TElement.Create(Name);
end;
constructor TElemDEsc.Create(aName:string ;aHW_Time,aCPU_Time:LongWord);
begin
inherited Create(aName);
HW_Time:=aHW_Time;
CPU_Time:=aCPU_Time;
end;
function TElemDEsc.Copy:TElement;
begin
Result:=TElemDesc.Create(Name,HW_Time,CPU_Time);
end;
var
i:Integer;
ElArr:array[0..9] of TElement;
DEscArr:array[0..9] of TElemDesc;
El:TElement;
DEsc:TElemDesc;
Count:Integer=10;
begin
memchk;
Writeln('Creating Base');
El:=TElement.Create(Format('Elem %D',[1]));
for i:=0 to Count - 1 do
begin
ElArr[i]:=El.Copy;
ElArr[i].Name:=Format('Elem %D',[i+1]);
end;
Writeln('Creating Descendant');
Desc:=TElemDesc.Create(Format('DEsc %D',[1]),100,100);
for i:=0 to Count - 1 do
begin
DescArr[i]:=TElemDesc(DEsc.Copy);
DescArr[i].Name:=Format('DEsc %D',[i+1]);
inc(DEscArr[i].HW_Time);
inc(DEscArr[i].CPU_Time);
end;
writeln('Freeing Arrays Elements');
for i:=0 to Count - 1 do
ElArr[i].Free;
writeln('Freeing Arrays DEscendant');
for i:=0 to Count - 1 do
DescArr[i].Free;
writeln('Freeing vars');
desc.Free;
El.Free;
readln;
end.
мемчек исключений не выдает.
В общем все должно работать и вроде работает так что ищу ошибки в коде своей проги