Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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
15-1170338247
Похвола
2007-02-01 16:57
2007.02.25
Перебор


2-1170255228
Гость_
2007-01-31 17:53
2007.02.25
Заголовок в гриде сделать вертикальным


5-1149076516
MaxDAG
2006-05-31 15:55
2007.02.25
Ошибка при изменении с TForm.Paren


1-1167203119
TCrash
2006-12-27 10:05
2007.02.25
Zlib потоки (TDecompressionStream)


15-1170170721
Marker
2007-01-30 18:25
2007.02.25
Программа на заказ





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский