Форум: "Основная";
Текущий архив: 2007.02.25;
Скачать: [xml.tar.bz2];
ВнизРабота со строками приводит к ошибкам при выделении памяти Найти похожие ветки
← →
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;
Скачать: [xml.tar.bz2];
Память: 0.52 MB
Время: 0.042 c