Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 2 цикла в потоке сжирают память  [new]
Sergey-2008
Member

Откуда:
Сообщений: 103
Доброе время суток,
имеется поток, который каждые 10 сек, читает лог.
В нем имеется 2 цикла, которые анализируют последнюю строку лога, и выделяют из нее значения нужных мне параметров (для отображения их в программе). И как показали опыты, эти циклы почему-то сжирают память (если их закоментировать то с память сжираться не будет)
procedure TFileReadThread.UpdTemp1;
begin
  FMain.edTemp1.Clear;
  FMain.edTemp1.Text := Pr_ValTemp;
end;
 
procedure TFileReadThread.CLEAR_VALUE_VIDEO;  
begin
  Pr_ValGPU := '';
  Pr_ValTemp := '';
  Synchronize(UpdGPU0);
  Synchronize(UpdTemp0);
  Synchronize(UpdGPU1);
  Synchronize(UpdTemp1);
end;
 
procedure TFileReadThread.Execute;
var
  LFile: TStringList;
  w, LIndex, LIndex1, LNumGPU, L_Length: integer;
  q, LValue, LStringParams: string;
  LValueTrue: boolean;
begin
  while not Terminated do
  begin
    try
      CLEAR_VALUE_VIDEO;
      Pr_Status := 'File begin reading';
      Pr_Status_Color := clGreen;
      Synchronize(UpdStatus);
 
      LFile := TStringList.Create;
      LFile.LoadFromFile(PathFile);  
//q:=LFile.Strings[1];                                  
//w:=LFile.Count;
      L_Length := LFile.Count-1;
      LStringParams := '';
      LValueTrue := false;
      LValue := '';
      LNumGPU := 0;
 
      for LIndex := L_Length downto 0 do
        if Pos('GPU0', LFile.Strings[LIndex]) <> 0 then
        begin
          LStringParams := LFile.Strings[LIndex];
          for LIndex1 := 0 to length(LStringParams) do
          begin
            if (LStringParams[LIndex1] in ['0'..'9']) then
              LValue := LValue+LStringParams[LIndex1]
            else
              if ((LStringParams[LIndex1] = '.')
                or (LStringParams[LIndex1] = ','))
                and (LValue <> '') then
              begin
                LValue := LValue+'.';
                LValueTrue := true;
              end
              else 
              begin
                if (LStringParams[LIndex1] = ' ')
                  and (LValueTrue) then
                begin
                  if (FMain.edGPU0.Text = '')
                    and (LNumGPU = 0) then
                    begin
                      Pr_ValGPU := LValue;
                      Synchronize(UpdGPU0);   
                    end;
                  if (FMain.edGPU1.Text = '')
                    and (LNumGPU = 1) then
                    begin
                      Pr_ValGPU := LValue;
                      Synchronize(UpdGPU1);   
                    end;
                  inc(LNumGPU);  
                end  
                else LValueTrue := false;
                LValue := '';  
              end;
          end;  
          break;
        end;
 
      LValue := '';
      LNumGPU := 0;
      for LIndex := L_Length downto 0 do
        if Pos('GPU0 t=', LFile.Strings[LIndex]) <> 0 then
        begin
          LStringParams := LFile.Strings[LIndex];
          for LIndex1 := 0 to length(LStringParams) do
          begin
            if (LStringParams[LIndex1] in ['0'..'9']) then
              LValue := LValue+LStringParams[LIndex1]
            else
              begin
                if (LStringParams[LIndex1] = 'C') then
                begin
                  if (FMain.edTemp0.Text = '')
                    and (LNumGPU = 0) then
                    begin
                      Pr_ValTemp := LValue;
                      Synchronize(UpdTemp0);   
                    end;
                  if (FMain.edTemp1.Text = '')
                    and (LNumGPU = 1)  then
                    begin
                      Pr_ValTemp := LValue;
                      Synchronize(UpdTemp1);   
                    end;
                  inc(LNumGPU);  
                end  
                else LValueTrue := false;
                LValue := '';  
              end;
          end;  
          break;
        end;
 
        Pr_Status := 'File end reading';
        Pr_Status_Color := clGreen;
        Pr_Sleep := IntToStr(ASleep);
//        ASleep := ASleep*1000;
        Synchronize(UpdStatus);
 
        FreeAndNil(LFile);
    except
    on E: Exception do
      begin
        Pr_Status := 'Not access to file';
        Pr_Status_Color := clRed;
        Synchronize(UpdStatus);
        FreeAndNil(LFile);
      end
    end;
  end;  
end;

что в этих циклах может память не отдавать... теряюсь в догадках

Заранее спасибо за ответ
7 янв 18, 22:35    [21086578]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45678

Sergey-2008
что в этих циклах может память не отдавать... теряюсь в догадках

FastMM + FullDebugMode помогут найти ответ на этот вопрос.

Posted via ActualForum NNTP Server 1.5

7 янв 18, 22:48    [21086612]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Sergey-2008
Member

Откуда:
Сообщений: 103
Да еще если поток зациклить, то окажеться что с памятью будет все норм., т.е. программа ее не будет захламлять
7 янв 18, 23:03    [21086644]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
чччД
Guest
Sergey-2008,

кода мало.
Например, ты в цикле обращаешься к CLEAR_VALUE_VIDEO, в которой сбрасываешь строки:

  Pr_ValGPU := '';
  Pr_ValTemp := '';

Что за Pr_ValGPU, Pr_ValTemp? Если это - "глобальные" переменные, живущие вне контекста нити - вот тебе и утечка.
7 янв 18, 23:06    [21086648]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Sergey-2008
Member

Откуда:
Сообщений: 103
чччД,

type
  TFileReadThread = class(TThread)
    private
    { Private declarations }
  protected
    Pr_Sleep, Pr_ValTemp0, Pr_ValTemp1, Pr_ValGPU0, Pr_ValGPU1, PathFile, Pr_Status: string;
    Pr_Status_Color: TColor;
    ASleep: integer;
    procedure Execute; override;
    procedure CLEAR_VALUE_VIDEO;
    procedure EDIT_VALUE_VIDEO;
    procedure UpdErrStatus;    
  public

    constructor Create(APathFile: String;
                       A_Sleep: integer);      
  end;
7 янв 18, 23:46    [21086737]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Sergey-2008
Member

Откуда:
Сообщений: 103
Но в "Pr_ValTemp", "Pr_ValGPU" хранятся только цифры
Каждый раз при выполнени потока, память увеличивается на 100КБ. (всего я храню в переменных 4 числа)
7 янв 18, 23:52    [21086751]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Док
Member

Откуда: Казань
Сообщений: 5701
Sergey-2008
имеется поток, который каждые 10 сек, читает лог.

а где в приведенном коде участок, который подтверждает данное заявление?

я к тому, что цикл без слипа
while True do
begin
//sleep(1000);
end;

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

К сообщению приложен файл. Размер - 52Kb
8 янв 18, 01:23    [21087034]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
чччД
Guest
Док,

похоже, ТС исследует уязвимость типа Meltdown. :)
8 янв 18, 01:34    [21087067]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Док
Member

Откуда: Казань
Сообщений: 5701
чччД,

ТС, похоже, только начал изучать потоки. До сообщений в основной поток пока не дошел. Видишь, как Synchronize интенсивно использует. Следующим этапом будет попытка использовать компонент wadman'а :)
8 янв 18, 08:36    [21087207]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
defecator
Member

Откуда:
Сообщений: 38569
а вот тут явно не с нуля надо индекс перебирать

  for LIndex1 := 0 to length(LStringParams) do
          begin
            if (LStringParams[LIndex1] in ['0'..'9']) then
8 янв 18, 10:05    [21087265]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
_Vasilisk_
Member

Откуда: Украина, Харьков
Сообщений: 10487
Sergey-2008
while not Terminated do
Terminate не обнаружено
Sergey-2008
имеется поток, который каждые 10 сек, читает лог.
Никакой приостановки потока тоже не обнаружено.

Не создаете ли Вы каждые 10 секунд новый поток?
8 янв 18, 12:30    [21087390]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3527
Sergey-2008,

1. Удаляй созданные объекты всегда строго в try-finally;
2. Полностью откажись от synchronize.

Потом можно будет дальше говорить.
8 янв 18, 13:47    [21087540]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
alekcvp
Member

Откуда:
Сообщений: 1088
YuRock
2. Полностью откажись от synchronize.

Кстати, а чем вы так синхронайз не любите? Они же вроде, в последних версиях, их переделали?
8 янв 18, 15:25    [21087677]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
defecator
Member

Откуда:
Сообщений: 38569
alekcvp
YuRock
2. Полностью откажись от synchronize.

Кстати, а чем вы так синхронайз не любите? Они же вроде, в последних версиях, их переделали?

но осадочек остался (с)

P.S. Я пользуюсь синхронайзом без зазрения совести, если вижу в нём необходимость.
8 янв 18, 15:52    [21087701]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45678

alekcvp
а чем вы так синхронайз не любите?

Его ограниченность на запуск методом без параметров и отсутствие возможности вернуть
результат лично меня напрягают. Глобальные переменные (даже локально-глобальные поля
класса) - зло.

Posted via ActualForum NNTP Server 1.5

8 янв 18, 16:12    [21087721]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
defecator
Member

Откуда:
Сообщений: 38569
Dimitry Sibiryakov
alekcvp
а чем вы так синхронайз не любите?

Его ограниченность на запуск методом без параметров и отсутствие возможности вернуть
результат лично меня напрягают. Глобальные переменные (даже локально-глобальные поля
класса) - зло.

глобальные переменные, "запуск методом без параметров" и "отсутствие возможности вернуть
результат" намешал опять в одну кучу ?
8 янв 18, 16:23    [21087751]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45678

Ну смотри: когда я использую SendMessage, то могу ему прямо передать два параметра и прямо
же вернуть число. Synchronize так не может, приходится использовать методы с побочными
эффектами и передавать значения через поля класса.
Когда я использую PostMessage, то работа продолжается без ожидания, чего Synchronize опять
же не может.

Posted via ActualForum NNTP Server 1.5

8 янв 18, 16:28    [21087758]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
kealon(Ruslan)
Member

Откуда: Нижневартовск
Сообщений: 3267
Dimitry Sibiryakov,

так ты не передавай, кто мешает в стэке выделить?
8 янв 18, 16:40    [21087775]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
defecator
Member

Откуда:
Сообщений: 38569
Dimitry Sibiryakov
Ну смотри: когда я использую SendMessage, то могу ему прямо передать два параметра и прямо
же вернуть число. Synchronize так не может, приходится использовать методы с побочными
эффектами и передавать значения через поля класса.
Когда я использую PostMessage, то работа продолжается без ожидания, чего Synchronize опять
же не может.

ну есть же разные необходимости синхронизации

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

пинг вещь длинная, городить вокруг этого SendMessage-PostMessage нет смысла
если раз в пять секунд произойдёт Synchronize от пинговального потока,
нет ничего страшного.

Это я просто пример привёл, если что
8 янв 18, 16:50    [21087788]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 45678

defecator
Это я просто пример привёл, если что

Забавно, что ты привёл как раз пример, где ни Synchronize, ни любая другая синхронизация
вообще не требуются.

Posted via ActualForum NNTP Server 1.5

8 янв 18, 17:02    [21087803]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
defecator
Member

Откуда:
Сообщений: 38569
Dimitry Sibiryakov
defecator
Это я просто пример привёл, если что

Забавно, что ты привёл как раз пример, где ни Synchronize, ни любая другая синхронизация
вообще не требуются.

с твоей точки зрения - не требуется
с моей точки зрения - требуется.
8 янв 18, 17:05    [21087810]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3527
defecator
если раз в пять секунд произойдёт Synchronize от пинговального потока,
нет ничего страшного
И чем этот пинговальный поток будет лучше таймера в главном потоке? Названием только красивым.
8 янв 18, 20:57    [21088191]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
defecator
Member

Откуда:
Сообщений: 38569
YuRock
defecator
если раз в пять секунд произойдёт Synchronize от пинговального потока,
нет ничего страшного
И чем этот пинговальный поток будет лучше таймера в главном потоке? Названием только красивым.

за 5 секунд произойдёт десяток попыток пинга внутри потока,
а результат вылезет наружу только раз в пять секунд.

Зачем главному потоку вообще знать о том, что там что-то такое постоянно работает ?
8 янв 18, 21:08    [21088222]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3527
alekcvp
YuRock
2. Полностью откажись от synchronize.

Кстати, а чем вы так синхронайз не любите? Они же вроде, в последних версиях, их переделали?
Не знаю, что там сейчас, но тем, что до D7, пользоваться было нельзя по большому ряду причин. К счастью, в этом и нет никакой необходимости.
Стандартный набор граблей synchronize можно увидеть и самому, посмотрев реализацию, ну например:
1. Вызов synchronize навсегда зависнет, если его вызвать до Application.Run;
2. Навсегда зависнет, если вообще и не планировался вызов Application.Run (dll, консоль,...);
3. Навсегда зависнет, если работает еще один цикл обработки сообщений, запущенный при обработке сообщения в Application.Run;
4. Невозможность управления потоками, висящими на synchronize. Другие методы синхронизации дают такую возможность.

Первые три пункта далеко не всегда зависят от разработчика. Поэтому если кто-то наговнокодил с synchronize - другим приходится мучиться или переделывать.
8 янв 18, 21:12    [21088237]     Ответить | Цитировать Сообщить модератору
 Re: 2 цикла в потоке сжирают память  [new]
YuRock
Member

Откуда: Донецк
Сообщений: 3527
defecator
YuRock
пропущено...
И чем этот пинговальный поток будет лучше таймера в главном потоке? Названием только красивым.

за 5 секунд произойдёт десяток попыток пинга внутри потока,
а результат вылезет наружу только раз в пять секунд.

Зачем главному потоку вообще знать о том, что там что-то такое постоянно работает ?
Я думал у тебя сам пинг в синхронайз делается раз в пять секунд.
8 янв 18, 21:15    [21088241]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить