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

Вниз

Работа со строками приводит к ошибкам при выделении памяти   Найти похожие ветки 

 
MegaVolt ©   (2006-12-28 16:34) [0]

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

LogFile:TFileStream;

procedure TLog.StartF(Str: string);
var
 s:string;
begin
 if not Enabled then Exit;
 s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;
 LogFile.Write(s[1],Length(s));
//  FlushFileBuffers(LogFile.Handle);
end;


Допускаю что дело не в этой функции а во вносимых ею задержках. Но как тогда искать в чём проблема?


 
Джо-со-смарта   (2006-12-28 16:43) [1]

Причем здесь какие-то задержки?


 
MegaVolt ©   (2006-12-28 16:53) [2]

>Причем здесь какие-то задержки?
Это была версия. В проге используется мультимедийный таймер возможно добавление задержек вызывает какие то эффекты. Если задержки не при чём тогда в чём дело? Как лечить?


 
Джо ©   (2006-12-28 17:29) [3]

> Как лечить?

Что лечить-то? Приведенный код вполне работоспособен. А «проблемы с выделением памяти и нестабильной работе программы» — не озвучены.


 
MegaVolt ©   (2006-12-28 17:37) [4]

К сожалению не могу точно описать потому что симптомов море. Прога падает с исключением. Иногда ругается на проблемы работы с памятью а именно в модуле getmem.inc. Иногда ругается на невозможность создания битмапа. Если же Enabled выставить в false все глюки пропадают. Может ли быть проблема с тем что данная функция вызывается очень часто (в каждой моей процедуре или функции) и возникают какие то проблемы при частом выделении памяти под стрококу.


 
Джо ©   (2006-12-28 17:44) [5]

> [4] MegaVolt ©   (28.12.06 17:37)
> К сожалению не могу точно описать потому что симптомов море.

Ну, и чем ты думаешь тебе смогут помочь в таком случае? Ясно одно — программа неверно написана :)


> Может ли быть проблема с тем что данная функция вызывается
> очень часто (в каждой моей процедуре или функции) и возникают
> какие то проблемы при частом выделении памяти под стрококу.

Я не слишком рискую, если предположу, что не может.


 
MegaVolt ©   (2006-12-28 17:52) [6]

>Я не слишком рискую, если предположу, что не может.
Я встречал глюк при частом выделении памяти маленькими кусками например в TMemoryStream почему не исключить такие же проблемы с выделением памяти под строки? Тем более если верить отладчику именно при этом и вознимкают ошибки (если судить по истории вызовов процедур)

Как ловить проблему если:
1. Место появления ошибки нестабильно
2. Строка с ошибкой находится в генофонде а не в моём коде
3. Добавление моего когда для записи логов способствуует появлению ошибок
4. Баг не повторяем. Т.е. действия приведшие к глюку при одном запуске не приводят к глюку во втором.


 
Anatoly Podgoretsky ©   (2006-12-28 17:57) [7]

> MegaVolt  (28.12.2006 17:52:06)  [6]

> 3. Добавление моего когда для записи логов способствуует появлению ошибок

Соотвественно ищи ошибку в другом месте.


 
MegaVolt ©   (2006-12-28 18:09) [8]

>Соотвественно ищи ошибку в другом месте.
Как? Что ловить какие характерные куски анализировать?


 
Sha ©   (2006-12-28 18:12) [9]

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

IsMultiThread:=TRUE;


 
isasa ©   (2006-12-28 23:43) [10]

Попробуй
procedure TLog.StartF(Str: string);
var
s:string;
begin
if not Enabled then Exit;
<мультимедийный таймер>.Disable;
s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;
LogFile.Write(s[1],Length(s));
//  FlushFileBuffers(LogFile.Handle);
<мультимедийный таймер>.Enable;
end;


 
SlymRO   (2006-12-29 04:33) [11]

procedure TLog.StartF(Str: string);
var
s:string;
begin
if not Enabled then Exit;
CriticalSection.Enter;
try
s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;
LogFile.Write(s[1],Length(s));
//  FlushFileBuffers(LogFile.Handle);
finally
CriticalSection.Leave;
end;
end;


 
Slym ©   (2006-12-29 04:39) [12]

Вау! Новогодняя амнистия!


 
Sha ©   (2006-12-29 10:14) [13]

> SlymRO   (29.12.06 04:33) [11]

Припарки вряд ли помогут менеджеру.


 
MegaVolt ©   (2006-12-29 10:55) [14]

Насколько я понимаю критические секции нужны чтобы данный кусок кода мог выполнялся только один раз и повторное обращение до окончания выполнения было бы невозможно. Почему это может помочь? Я не вижу ничего криминального в том что этот кусок кода будет выполнятся одновременно из нескольких мест.


 
Джо ©   (2006-12-29 11:05) [15]

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

Дык, как сказали, мультимедийный таймер выполняется в разных потоках. Поэтому и будут неприятности из-за паралельных обращений к глобальным переменным из разных потоков. А критические секции этому воспрепятствуют.


 
Sha ©   (2006-12-29 12:06) [16]

> Джо ©   (29.12.06 11:05) [15]
> А критические секции этому воспрепятствуют.


Нет. Они нисколько не препятствуют параллельным обращениям к менеджеру памяти.


 
MegaVolt ©   (2006-12-29 12:07) [17]

Т.е. проблема в множественном обращении к FileStream?


 
Sha ©   (2006-12-29 12:17) [18]

> MegaVolt ©   (29.12.06 12:07) [17]

Проблема может быть, например, в таком безобидном операторе:

s:="<"+IntToStr(GetTickCount-StartTime)+":"+str+#13+#10;

т.к. он требует перераспределения памяти, если параллельному потоку в
тоже самое время потребуются услуги менеджера.


 
Джо ©   (2006-12-29 12:22) [19]

> [16] Sha ©   (29.12.06 12:06)
> > Джо ©   (29.12.06 11:05) [15]
> > А критические секции этому воспрепятствуют.
>
> Нет. Они нисколько не препятствуют параллельным обращениям
> к менеджеру памяти.

В метод StartF нельзя будет «войти» из разных потоков. Поэтому и не будет никаких «параллельных обращений к менеджеру памяти». Разве не так?


 
MegaVolt ©   (2006-12-29 12:22) [20]

>Проблема может быть, например, в таком безобидном операторе
А похоже так и есть. Как тогда правильно делать ведение логов?


 
Sha ©   (2006-12-29 12:31) [21]

> Джо ©   (29.12.06 12:22) [19]
> В метод StartF нельзя будет «войти» из разных потоков

Согласен.

> Поэтому и не будет никаких «параллельных обращений к менеджеру памяти».

Не согласен.
Другой поток имеет полное право в это время создать какой-нить объект.


 
evvcom ©   (2006-12-29 12:42) [22]

Что-то я вас не пойму. Вы хотите сказать, что дельфовый менеджер памяти не потокобезопасен?


 
Sha ©   (2006-12-29 12:43) [23]

> MegaVolt ©   (29.12.06 12:22) [20]
> Как тогда правильно делать ведение логов?

Если поток всего один, то ничего дополнительно делать не надо.
Если 2 и больше - установить IsMultiThread=TRUE, например при помощи BeginThread
Если пишущих в лог 2 и больше - защитить процедуру записи крит секцией.


 
Sha ©   (2006-12-29 12:44) [24]

> evvcom ©   (29.12.06 12:42) [22]
> Что-то я вас не пойму. Вы хотите сказать, что дельфовый менеджер памяти не потокобезопасен?

Потокобезопасен, если потоки создавать средствами Делфи.


 
evvcom ©   (2006-12-29 12:47) [25]

> [23] Sha ©   (29.12.06 12:43)
> IsMultiThread=TRUE

А... Уже забыл, что раньше об этом говорилось.


 
AgainSlymRO   (2006-12-29 13:02) [26]

Сабрались старые бухарики под новый год и спорять по IsMultiThread...
CriticalSection на разделяемом несколькими потоками объекте должен быть априори, всегда!


 
AgainSlymRO   (2006-12-29 13:04) [27]

Я тут с одним уже спорил, так этот "один" втирал мне что строки string потокобезопасны! я ему на пальцах нарисовал что даже 1 байт не может быть потокобезопасным


 
evvcom ©   (2006-12-29 13:09) [28]

> [26] AgainSlymRO   (29.12.06 13:02)
> Сабрались старые бухарики под новый год

Гы, а ты вечный нарушитель? :)))


 
Sha ©   (2006-12-29 13:21) [29]

> AgainSlymRO   (29.12.06 13:02) [26]
> Сабрались старые бухарики под новый год и спорять по IsMultiThread...
> CriticalSection на разделяемом несколькими потоками объекте должен быть априори, всегда!

Ну да, конечно, на CriticalSection свет клином сошелся


 
MegaVolt ©   (2006-12-29 16:21) [30]

>я ему на пальцах нарисовал что даже 1 байт не может быть потокобезопасным
А можно ссылочку? Или повторить вывод? (я надеюсь нерассматривался случай побитового исправления байта?)



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

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

Наверх




Память: 0.52 MB
Время: 0.04 c
2-1170638798
Новичек
2007-02-05 04:26
2007.02.25
Динамический массив объектов.


2-1170852927
Рустам
2007-02-07 15:55
2007.02.25
Обновления в базе


2-1170003137
Kostafey
2007-01-28 19:52
2007.02.25
Динамическое формирование главного меню


1-1167208489
Yozch1
2006-12-27 11:34
2007.02.25
цвет хидера в VTV


4-1161082022
Elen
2006-10-17 14:47
2007.02.25
Вопрос по EnumChildWindows





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский