Форум программистов
 
О проблемах, например, с регистрацией пишите сюда - alarforum@yandex.ru, проверяйте папку спам! Обязательно пройдите активизацию e-mail, а тут можно восстановить пароль.

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Ответ
 
Опции темы
Старый 12.08.2009, 15:03   #1
cowboy
Форумчанин
 
Регистрация: 12.03.2009
Сообщений: 109
По умолчанию Мое приложение жрет оперативку

Добрый день! Вот в чем проблема..У меня в мое приложение через DDE идут данные . Там они обрабатываются и разбрасываются по стринггридам...Затем нужные данные с периодичностью в 60секундпишутся в файл. Потом программа записывает весь файл в массив и последние 1400 элементов выводится на график..При этом приложение в Диспетчере отображается при запуске, что забрано 17 мегабайт оперы..Затем это число постоянно растет и при уровне 23 мега начинает вылетать такой мессадж в эттаче..Причем программа продолжает работать.
Изображения
Тип файла: jpg 123123.jpg (3.1 Кб, 181 просмотров)
cowboy вне форума Ответить с цитированием
Старый 12.08.2009, 15:06   #2
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,002
По умолчанию

ну с сообщением все ясно...ошибка работы с массивом
а по поводу памяти...освобождать не забываете?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.08.2009, 15:17   #3
cowboy
Форумчанин
 
Регистрация: 12.03.2009
Сообщений: 109
По умолчанию

Цитата:
Сообщение от Пепел Феникса Посмотреть сообщение
ну с сообщением все ясно...ошибка работы с массивом
а по поводу памяти...освобождать не забываете?
А как это делается?
Я просто прописал массив в АРРЭЙи на каждой итерации таймера (5 сек) гоню туда весь файл (около 5 мегов) и забираю из него последние 1400 элементов!
А как освобождать память?
cowboy вне форума Ответить с цитированием
Старый 12.08.2009, 15:29   #4
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,002
По умолчанию

для массива(если он динамический)
SetLength(массив,0);
но потом обратно надо резервировать место
а вы уверенны что это не нормально?
один символ строки это один байт....а если текст?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.08.2009, 16:26   #5
cowboy
Форумчанин
 
Регистрация: 12.03.2009
Сообщений: 109
По умолчанию

я думаю что это не нормально..Он же не будет у меня постоянно так оперативку забивать? а если я планирую еще около 10 файлов опрашивать такой же величины? А почему он сразу после того как пройдет итерация таймера не освобождает массив по умолчанию?
Код:
procedure TPagesDlg.Timer3Timer(Sender: TObject);
var
iv_str:array[1..200000] of string;
iv,date,time,iv_cutt:array[1..w] of string;
index:textfile;
st,ti,temp,temp1,temp2:string;
i,j,count,p,point,koef,y,z,u,k:integer;
max,min,diap:real;
iv_d:array[1..w] of integer;
chart:TChart;
series:TLineSeries;
begin
AssignFile(index,'D:\volatility\volatility.txt');
reset(index);
u:=0;
i:=1;

While not EOF(index) do begin
ReadLn(index,st);

if u=strtoint(combobox1.text) then begin
iv_str[i]:=st;
u:=0;
i:=i+1;
end;

u:=u+1;
end;

CloseFile(index);

count:=i;
p:=0;
j:=1;
max:=0;
min:=100000;

for i:=(count-w) to count-1 do begin

if length(iv_str[i])>0 then begin
iv_cutt[j]:=iv_str[i];
date[j]:=copy(iv_str[i],6,8);
time[j]:=copy(iv_str[i],15,6);
iv[j]:=copy(iv_str[i],22,10);
p:=0;
p:=pos(',',iv[j]);
if p>0 then delete(iv[j],p,10);
delete(iv[j],6,10);
iv[j]:=iv[j];
 if strtofloat(iv[j])>max then max:=strtofloat(iv[j]);
 if strtofloat(iv[j])<min then min:=strtofloat(iv[j]);
j:=j+1;
end;

end;

chart:=chart1;

With chart do begin
Left:=0;
Top:=0;
Width:=w;
Height:=h;
View3D:=false;
Visible:=True;
MarginBottom:=1;
Marginleft:=1;
Marginright:=2;
Margintop:=1;
end;

With Chart.Title.Text do
begin
	Clear;
	Add('Implayed Volatility');
end;

series:=TLineSeries.Create(chart);
chart.RemoveAllSeries;

for i:=1 to w do begin
 series.AddXY(i,strtofloat(iv[i]),'',RGB(0,0,255));
end;

chart.AddSeries(series);
вот код той процедуры которая жрет память

Последний раз редактировалось Stilet; 17.08.2009 в 14:18.
cowboy вне форума Ответить с цитированием
Старый 12.08.2009, 16:36   #6
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,002
По умолчанию

а может дело в чарте?
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 12.08.2009, 17:42   #7
s.Creator
Форумчанин
 
Регистрация: 28.09.2008
Сообщений: 344
По умолчанию

Цитата:
Сообщение от cowboy Посмотреть сообщение
Код:
chart.RemoveAllSeries;
немного поэкспериментировал
RemoveAllSeries - не уничтожает старые TLineSeries а только удаляет их из графика - вот они и накапливаются.

причем при таком добавлении у меня при закрытии приложения еще и AV выскакивало

заменил на
Код:
if chart.SeriesCount > 0 then  chart.Series[0].Free;
(для нескольких графиков надо в цикле удалять)
и в
Код:
procedure TForm1.FormDestroy(Sender: TObject);
begin
if chart.SeriesCount > 0 then  chart.Series[0].Free;
end;
Стало работать нормально и без AV
s.Creator вне форума Ответить с цитированием
Старый 17.08.2009, 13:32   #8
cowboy
Форумчанин
 
Регистрация: 12.03.2009
Сообщений: 109
По умолчанию

Спасибо за помощь! А что может быть за ошибка работы с массивом? Из-за чего обычно такие происходят?
cowboy вне форума Ответить с цитированием
Старый 17.08.2009, 13:42   #9
Пепел Феникса
Старожил
 
Аватар для Пепел Феникса
 
Регистрация: 28.01.2009
Сообщений: 21,002
По умолчанию

обращение к несуществующему элементу массива
Код:
for i:=(count-w) to count-1 do begin
видимо получается что i =-1 иногда, а не ноль
Хорошо поставленный вопрос это уже половина ответа. | Каков вопрос, таков ответ.
Программа делает то что написал программист, а не то что он хотел.
Функции/утилиты ждут в параметрах то что им надо, а не то что вы хотите.
Пепел Феникса вне форума Ответить с цитированием
Старый 17.08.2009, 18:22   #10
s.Creator
Форумчанин
 
Регистрация: 28.09.2008
Сообщений: 344
По умолчанию

Вообще то в первом посте, если я не ошибаюсь, ошибка индекса (= -1) при обращении к TList, TStringList или одному из их наследников.
Про массивы:
Если включена опция компилятора "Range checking", то в программу добавляется проверочный код который при выходе индекса за границы массива выдает ошибку "Range check error"
Код:
iv_str[i]:=st; // при i > 200000
Код:
for i:=(count-w) to count-1 do begin // при count <= w
Обычно используется для отладки.
Если опция выключена - ошибка не выдается, НО при этом если индекс выходит за рамки массива, Вы залезаете в память не выделенную для этого массива, что может привести к очень неожиданным результатам, изменением других переменных, изменением стека возврата из процедур,
что может привести к ошибкам вплоть до полного краха программы.
Кстати попробовал немного оптимизировать код (зачем для записи 1400 точек массив в 200000 что умножить на 30 символов в строке составит 6 MB).
Заодно вроде решил проблему с выходом за пределы массивов.
Код:
procedure TPagesDlg.Timer3Timer(Sender: TObject);
var
  iv_str:array[1..w] of string;
  iv,date,time,iv_cutt:array[1..w] of string;
  index:textfile;
  st,ti,temp,temp1,temp2:string;
  i,j,count,p,point,koef,y,z,u,k:integer;
  max,min,diap:real;
  iv_d:array[1..w] of integer;
  chart:TChart;
  series:TLineSeries;
  FullArray: boolean;
  PropuskStrok: integer;

  procedure IncCykle(ind: integer);
  begin
    Inc(ind);
    if ind > w then
    begin
      ind := 1;
      FullArray := true; // заполнили массив хотябы один раз
    end;
  end;

begin
  AssignFile(index,'D:\volatility\vol atility.txt');
  reset(index);
  u:=0;

  FullArray := false;
  i:=0;
  PropuskStrok := strtoint(combobox1.text); // зачем переводить строку в число до 200000 раз ?
  
  While not EOF(index) do
  begin
    ReadLn(index,st);
    if u = PropuskStrok then
    begin
      IncCykle(i);
      iv_str[i] := st;
      u:=0;
    end
    else
      u := u+1; // 0 - все строки, 1 - через одну ...
  end;

  CloseFile(index);

  if FullArray then
  begin
    count := w;
  end
  else
  begin  // считано всего i строк < w
    count := i;
    i := 0;
  end;

  p:=0;
  j:=0;
  max:=0;
  min:=100000;

  for i:=1 to count do
  begin
    IncCykle(i);
    if length(iv_str[i]) > 0 then
    begin
      Inc(j);
      iv_cutt[j]:=iv_str[i];
      date[j]:=copy(iv_str[i],6,8);
      time[j]:=copy(iv_str[i],15,6);
      iv[j]:=copy(iv_str[i],22,10);
      p:=0;
      p:=pos(',',iv[j]);
      if p>0 then
        delete(iv[j],p,10);
      delete(iv[j],6,10);
      // iv[j]:=iv[j]; - этого вообще не понял
      if strtofloat(iv[j])>max then
        max:=strtofloat(iv[j]);
      if strtofloat(iv[j])<min then
        min:=strtofloat(iv[j]);
    end;
  end;

  chart:=chart1;

  With chart do
  begin
    Left:=0;
    Top:=0;
    Width:=w;
    Height:=h;
    View3D:=false;
    Visible:=True;
    MarginBottom:=1;
    Marginleft:=1;
    Marginright:=2;
    Margintop:=1;
  end;

  With Chart.Title.Text do
  begin
    Clear;
    Add('Implayed Volatility');
  end;

  while chart.SeriesCount > 0 do
    chart.Series[0].Free;

  series:=TLineSeries.Create(chart);

  for i:=1 to j do // в массивы отфильтровано j строк
  begin
    series.AddXY(i,strtofloat(iv[i]),'',RGB(0,0,255));
  end;

  chart.AddSeries(series);
end;
проверял только на компиляцию.
s.Creator вне форума Ответить с цитированием
Ответ

Здесь нужно купить рекламу за 20 тыс руб в месяц! ) пишите сюда - alarforum@yandex.ru
Без учёта ботов - 20000 человек в день, 350000 в месяц.

Опции темы


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
можно ли вылечить оперативку? Don_Omar Железо 16 23.03.2009 14:27
Как уменьшить мое первое окно BOPOHA Assembler - Ассемблер (FASM, MASM, WASM, NASM, GoASM, Gas, RosAsm, HLA) и не рекомендуем TASM 6 29.12.2007 17:57
Какое-то приложение жрет трафик пыхта4ог Свободное общение 22 13.11.2007 15:12
DBE жрет оракловкие ошибки, как их выудить ? Iuliy БД в Delphi 2 21.03.2007 13:44
ООП мое первое начало cross Общие вопросы Delphi 1 18.03.2007 21:58


Проекты отопления, пеллетные котлы, бойлеры, радиаторы
интернет магазин respective.ru
Пеллетный котёл Emtas
котлы EMTAS
Здесь нужно купить рекламу за 7 тыс руб в месяц! )
пишите сюда - alarforum@yandex.ru
ИКС 840