Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.04.2013, 00:13   #1
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию проблемы освобождения ресурсов

Часть1:
Спасайте! Мир перевернулся вверх дном!
вот скажите мне пожалуйста, что в этом мире не так??
я всегда считал что Create - это создание объекта,
а именно - выделение необходимого количества памяти под объект,
а Destroy - наоборот, уничтожение объекта, его еще называют "освобождение ресурсов".
т.е. это освобождение памяти, т.е. если занимал компонент 100 байт памяти,
то после его удаления, он должен занимать 0 байт памяти, разве нет?

при этом, все попытки обращения к удаленному объекту должны заканчиваться в Access Violation -
ведь даже если ссылка осталась - объекта то уже НЕТ, память очищена!

Часть2:
и вот что я делаю:

берем обычный TPanel, берем массив N:array of TPanel,

и по кнопке1 создаем 10000 панелек:

for i:=0 to 10000 do // 10001, но это не суть.
begin
d:=Length(N);
SetLength(N,d+1);
N[d]:=TPanel.Create(self);
end; //поправьте, если я ошибаюсь, но по-моему с циклом все правильно.

а по кнопке2 удаляем все панельки:

for i:=0 to Length(N)-1 do N[i].Free; // по-моему тоже все предельно просто и ошибиться здесь негде...


Часть3:
теперь, исходя из логики, описанной в Части1, если мы нажмем кнопку1, а потом кнопку2,
то количество памяти, занимаемое программой не изменится. Поправьте, если я ошибаюсь.
НО!
Запускаем проект, смотрим в диспетчере задач (Alt+Ctrl+Del)
сколько памяти занимает программа - у меня ~3.5 mb
Теперь жмем кнопку1 (создаем 10000 панелек)
память потихоньку растет, у меня дошло до ~14 mb и остановилось
Теперь жмем кнопку2 (удаляем все панельки)
память сокращается только до ~8 mb, хотя по логике
она должна вернуться к ~3.5 mb (мы ведь удалили все что создали)

теперь меня мучает вопрос: что не так?
что занимает дополнительные ~4.5 mb?

Заранее спасибо! =)
xrob вне форума Ответить с цитированием
Старый 17.04.2013, 00:28   #2
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

в диспетчер задач смотреть не надо, и все ок.
eval вне форума Ответить с цитированием
Старый 17.04.2013, 00:30   #3
BDA
МегаМодератор
СуперМодератор
 
Аватар для BDA
 
Регистрация: 09.11.2010
Сообщений: 7,289
По умолчанию

Написал так:
Код:
var
  N: array of tpanel;

const
  k = 20000;

procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  setlength(N, k);
  for i := 0 to k - 1 do
    N[i] := tpanel.Create(self);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  i: integer;
begin
  for i := 0 to k - 1 do
    N[i].Free;
  setlength(N, 0);
end;

end.
Менеджер памяти решил не возвращать всю память для последующего ускорения действий (насколько можно судить "по интернетам"). Ведь при повторном нажатии кнопок памяти больше не занимает (т.е. верхний предел не меняется).
Пишите язык программирования - это форум программистов, а не экстрасенсов. (<= это подпись )
BDA вне форума Ответить с цитированием
Старый 17.04.2013, 00:31   #4
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Вроде освобождение динамических массивов не так происходит? нет?
UPD:
Ладно, я не прав)
UPD2:
Все таки вот эту строку я и ждал: "setlength(N, 0);"
alextrof94$gmail.com

Последний раз редактировалось alextrof94; 17.04.2013 в 00:33.
alextrof94 вне форума Ответить с цитированием
Старый 17.04.2013, 00:49   #5
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

Цитата:
в диспетчер задач смотреть не надо, и все ок.
хм, у меня были мысли что диспетчер может врать...
а куда тогда смотреть? как узнать сколько места программа занимает?

alextrof94, виноват =)
сообщение для форума я писал заново, а не копипастил из проги.
а там SetLength(N,0) у меня конечно же был,
но даже если бы его и не было, N - это массив указателей по сути,
каждый из них весит 4 байта.
чтобы такой массив занимал 4 метра, его длина должна быть 1 000 000,
т.е. 4 байта х 1 000 000


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

Последний раз редактировалось xrob; 17.04.2013 в 00:53.
xrob вне форума Ответить с цитированием
Старый 17.04.2013, 00:54   #6
alextrof94
Форумчанин
 
Регистрация: 16.03.2013
Сообщений: 599
По умолчанию

Еще можно попробовать заюзать freeandnil(N[i]), может он полностью освободит память, но как было сказано выше, программа по завершении все равно все освободит.
alextrof94$gmail.com
alextrof94 вне форума Ответить с цитированием
Старый 17.04.2013, 01:13   #7
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

Цитата:
Кстати, есть какой-нибудь предел количества создаваемых компонентов?
насколько мне известно только ресурсами ограничивается, ну например хэндлы закончатся в системе
eval вне форума Ответить с цитированием
Старый 17.04.2013, 01:13   #8
eval
Подтвердите свой е-майл
 
Регистрация: 29.08.2012
Сообщений: 4,011
По умолчанию

тут като была тема про то сколько калькуляторов можно стартонуть сразу
eval вне форума Ответить с цитированием
Старый 17.04.2013, 19:31   #9
s-andriano
Старожил
 
Аватар для s-andriano
 
Регистрация: 08.04.2012
Сообщений: 3,229
По умолчанию

Цитата:
Сообщение от xrob Посмотреть сообщение
for i:=0 to 10000 do // 10001, но это не суть.
begin
d:=Length(N);
SetLength(N,d+1);
N[d]:=TPanel.Create(self);
end; //поправьте, если я ошибаюсь, но по-моему с циклом все правильно.
Отнюдь.
НИкогда так не делайте.
SetLength - "тяжелая" операция, ее нцужно выносить из цикла.
Вы умудрились написать код так, что он вместо ~10000 операций совершает ~100000000.
Цитата:
Запускаем проект, смотрим в диспетчере задач (Alt+Ctrl+Del)
сколько памяти занимает программа - у меня ~3.5 mb
Цитата:
хм, у меня были мысли что диспетчер может врать...
а куда тогда смотреть? как узнать сколько места программа занимает?
А кто сказал, что он врет?

Вот, скажем, идете Вы по улице и видите дом с табличкой "ул. Ленина 39".
- Ага, - думаете Вы, - 39 - это высота здания в метрах.
А потом оказывается, что высота - всекго 18 метров.
Выходит, табличка врет?

Диспетчер задач показывает все правильно, но совсем не то, что Вы хотите.
s-andriano вне форума Ответить с цитированием
Старый 17.04.2013, 22:02   #10
xrob
Форумчанин
 
Регистрация: 18.10.2010
Сообщений: 419
По умолчанию

s-andriano, если уж изволите проводить аналогию с домом,
то более похоже это выглядело бы так:
вот скажем иду я по улице и вижу дом с табличкой "высота 20",
и видя это я могу совершенно закономерно подумать, что это высота дома 20 м.
а на самом деле табличка имела в виду что это высота потолков в доме 20 м.

но в общем я вас понял:
диспетчер показывает сколько памяти винда предоставляет программе,
а не сколько программа реально занимает.

Цитата:
Отнюдь.
да нет, с точки зрения логики цикл написан правильно.
хотя с тем что он не рационален спорить не буду...
просто раньше я никогда не задумывался о таких простых операциях как SetLength,
но по ходу не так она и проста... Как она работает?
Перекладывает ВЕСЬ массив на новое место?
xrob вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
проблемы освобождения ресурсов xrob Общие вопросы Delphi 2 17.04.2013 02:40
Процедурой освобождения памяти на assembler t2skler Общие вопросы Delphi 1 10.02.2011 13:52
Проблема освобождения файла в DSPAck PIKACHU Мультимедиа в Delphi 11 04.12.2009 17:13
Проблема освобождения ресурсов при работе с COM (IHTMLDocument2) Антон Ю.Б. Общие вопросы Delphi 0 27.07.2009 17:34
Проблемы с добавлением ресурсов?? HunterMan Win Api 4 12.06.2008 02:33