Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.04.25;
Скачать: CL | DM;

Вниз

Надежность программ на Delphi   Найти похожие ветки 

 
vertal   (2004-04-05 01:11) [0]

Хочу обсудить надежность программ на Delphi
Меня смущает работа GetMem:
Предположим , есть такой код

...
Var
 ...
 p:Pointer;
 ...
Begin
 ...
 if (MaxAvail>=256)then GetMem(p,256);
 ...
End.

Я не уверен , что на "then" не произойдет передача управления
другому процессу в Windows , и этот другой процесс может отобрать себе
часть памяти , в результате чего отработка GetMem(p,256) будет
неуспешной.Получается , что пользоваться встроенным менеджером памяти вообще
нельзя? Или все GetMem() заключать в блоки try?
И еще операции со строками :что , получается , что каждый оператор , который
может приводить к увеличению длины динамической строки , нужно заключать в
блок try?

 try
   s1:=s1+#13#10;
 except
   ...
 end;


 
Fay ©   (2004-04-05 02:52) [1]

Про try - это правильно мыслишь. Тока вот всё, что ты тут нам так здорово расписал не имеет никакого отношения к Delphi лично.
Это относится ко всем проограммам.


 
Broot   (2004-04-05 03:05) [2]

Вообще то у винды есть виртуальная память и всякие там файлы подкачки. Так что, чтобы исчерпать память, нужно очень постараться...


 
Fay ©   (2004-04-05 03:11) [3]

Ничего особенного для этого не требуется. Я однажды попытался открыть 15Mb-й xml Explorer-ом... Когда он  сожрал 1.5 Gb и попросил ещё пришлось его пристрелить.


 
KSergey ©   (2004-04-05 08:06) [4]

> vertal   (05.04.04 01:11)

У вас несколько превратные представления о надежных программах.

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

Так, например, в связи с GetMem напрашивается следующий шаблонный код:

GetMem(p, ..);
try
 ...// работаем с выделенной памятью
finally
 FreeMem (p);
end;


Что тут важно: если нам не удасться получить память (в GetMem) - система сгенерит исключение, работы процедуры будет прервана, пользователь получить сообщение и нехватке памяти.
Если память таки выделится - то в случае каких либо проблем (исключений) внутри блока try/finally мы обязательно, гарантированно вызовем FreeMem и освободим память. Пользователь так же получит сообщение о возникшей проблеме.
Только не надо вносить GetMem в try/finally!! почему? подумайте сами, что произойдет в этом случае при ошибах на выделении памяти.

Про строки - я вообще не панял. Что беспокоит?? Дельфи гарантирует, что при любых проблемах память, распределяемая ею динамически (в частности, под строки), будет освобождена. О чем беспокоимся??


 
Verg ©   (2004-04-05 08:48) [5]

Где-то я видел такие дела

A := B;
if A <> B then { Тут запись в лог-файл об ошибке RAM}

А вообще, как тут не вспомнить про старую деву, свечку и то, что она на свечку надевала, дабы "Чего не вышло"...


 
Fay ©   (2004-04-05 08:50) [6]

>> A := B;
>> if A <> B then { Тут запись в лог-файл об ошибке RAM}
Это уже клиника... 8)


 
Verg ©   (2004-04-05 08:55) [7]


> Это уже клиника... 8)


- это называется паранойя.


 
Fay ©   (2004-04-05 08:57) [8]

Во спасибо! А я всё думал, как это слово пишется. 8). А то, бывает, само просится, чтобы его написали, а - никак ... Ну и получается, что "голова тоже на обочине".


 
Verg ©   (2004-04-05 10:00) [9]

Нет, Fay, уж какие тут к черту шутки - дело сердёздное:
http://www.psychiatry.ru/lib/smul_paranoja/index.cgi?11


 
vertal   (2004-04-06 00:23) [10]

2 Fay
> Про try - это правильно мыслишь. Тока вот всё, что ты тут нам
> так здорово расписал не имеет никакого отношения к Delphi лично.
>Это относится ко всем проограммам.
По-моему , это не относится ко всем программам .Так , в СИ , если не ошибаюсь , основной функцией для выделения памяти является malloc , а она при неудаче просто возвращает NULL вместо всяких исключений , и это можно проверить и прореагировать.Тут не возникает возможность изменения распределения памяти другим приложением между ее проверкой и фактическим выделением .


 
Alex Konshin ©   (2004-04-06 00:41) [11]

Начальный вопрос поставлен неверно: GetMem выделяет память в виртуальной памяти процесса, так что никакой другой процесс на это повлиять не сможет. Если же речь идет про потоки, то GetMem работает немного по-другому в случае многопоточного приложения, есть даже специальный флаг для многопоточного приложения и этот флаг устанавливается именно для менеджера памяти. Как он называется - на вскидку не помню, а искать сейчас лень, да и не об этом вопрос был.


 
KSergey ©   (2004-04-06 08:50) [12]

>  [10] vertal   (06.04.04 00:23)
> По-моему , это не относится ко всем программам .Так , в
> СИ , если не ошибаюсь , основной функцией для выделения
> памяти является malloc , а она при неудаче просто возвращает
> NULL вместо всяких исключений , и это можно проверить и
> прореагировать.Тут не возникает возможность изменения распределения
> памяти другим приложением между ее проверкой и фактическим
> выделением
.

Я правда совершенно не понял выделенную фразу, но не понятно чем вас смущает: в Си после выделения - вы проверяли. А тут - не надо ничего проверять! Если что-то не пройдет - будет исключение, ф-ция прервется - вот и все. Проверять-то зачем?? Если не получилось - то что вы хотите сделать?


 
Miwa ©   (2004-04-06 11:19) [13]

Все же рискну спросить по вопроссу KSergey © (05.04.04 08:06)[4]:
А почему нельзя GetMem вносить внутрь блока try? Всю жизнь имення так и делал, кстати говоря.


 
Fay ©   (2004-04-06 11:36) [14]

В нек. смысле, нет блоков try. Есть блоки try..except и try..finally. Вы про какой спросили?

P.S
Сам знаю, что я не KSergey 8)


 
Андрей Сенченко ©   (2004-04-06 11:36) [15]

Miwa ©   (06.04.04 11:19) [13]

Потому что суперджинс.

Сравните 2 варианта

try           try
 GetMem()      GetMem()
finally       except
 FreeMem()     FreeMem()
end           end


 
Матлабист   (2004-04-06 11:49) [16]

var
 A: Pointer;
begin
 A := SysGetMem(1024*1024*1024);
 if not Assigned(A) then ShowMessage("SysGetMem returns nil");
end;


Только Exception намного удобнее...


> А почему нельзя GetMem вносить внутрь блока try? Всю жизнь
> имення так и делал, кстати говоря.


Ошибка при выделении памяти приведет к тому, что FreeMem вызвется для блока, для которого память не была выделена. В Windows это не страшно --- Invalid pointer operation. А в DOS могла біть непритность вроде зацикливания ;)


 
vertal   (2004-04-07 01:33) [17]

> Проверять-то зачем??
> Если не получилось - то что вы хотите сделать?
Положим , у меня есть два варианта решения задачи:первый требует больше памяти , но быстрее .Если он не проходит , то я могу попытаться применить второй вариант.Мне было бы удобней просто проверять указатель на Nil.Хотя , если ,как говорит Alex Konshin , "GetMem выделяет память в виртуальной памяти процесса, так что никакой другой процесс на это повлиять не сможет." , то и вариант с проверкой через MaxAvail меня устраивает.Хотя еще больше мне понравился вариант с SysGetMem.


 
Alex Konshin ©   (2004-04-07 02:56) [18]

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

А кто мешает самому выделять память? Я, например, в некоторых случаях, когда нужна память на время, просто беру память страницами с помощью VirtualAlloc, а когда нужно освободить отдаю их тоже всем скопом.



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

Текущий архив: 2004.04.25;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.024 c
3-1080569640
Алексей П.
2004-03-29 18:14
2004.04.25
Друзья! Помогите с параметрами TSQLConnection


14-1080974831
Knight
2004-04-03 10:47
2004.04.25
Кто знает где обитают мастера по ремонту оборудования?


14-1080991331
VID
2004-04-03 15:22
2004.04.25
Имея 1 гиг ОЗУ как лучше всего поступить со свопом винды ?


1-1081153338
Tanuki
2004-04-05 12:22
2004.04.25
Перехват значения


6-1074424924
elected
2004-01-18 14:22
2004.04.25
TWebBrowser Открытие нового окна в том же окне