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

Вниз

Не хватает памяти.   Найти похожие ветки 

 
MacroDenS ©   (2004-07-15 16:44) [40]

А на мой взгляд,
автор при объявлении:

type
TMyMassiv = record
v1: String;
v2: String;
v3: Integer;
end;{record}

использует переменные типа стринг неопределенной длины!
а такая строка может занимать и до 2Гбт.
Если у тебя строки не очень длинные ( в пределах 255 символов), то лучше задай так:

TMyMassiv = record
v1: String[255];
v2: String[255];
v3: Integer[255];
end;{record}

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


 
Суслик   (2004-07-15 16:47) [41]

ага, расходов будет в раз в 5 в среднем больше :)))


 
opoloXAI   (2004-07-16 11:41) [42]

Добрый день. Я ркшил сделать так:

type
 TmySearchRec = record
   Size: Integer;
   Name: TFileName;
   Path: String;
 end;
 PmySearchRec = ^TmySearchRec;
 TSameForm = class(TForm)
 ...
 private
   { Private declarations }
   kolFls: Int64;
   GetPamat: Int64;
   ListOfFiles: TList;
   procedure ScanDir(StartDir: string);
   procedure AddFile(Lst: TList; SchRec: TSearchRec; Dir: String);
   procedure KillAllFiles(Lst: TList);
 public
   { Public declarations }
 end;

procedure TSameForm.FormCreate(Sender: TObject);
begin
    ListOfFiles:=Tlist.Create;
end;

procedure TSameForm.FormDestroy(Sender: TObject);
begin
    ListOfFiles.Free;
end;

procedure TSameForm.AddFile(Lst: TList; SchRec: TSearchRec; Dir: String);
   p: PmySearchRec;
begin
    kolFls:=kolFls+1;
    New(P);
    P^.Size:=SchRec.Size;
    P^.Name:=AnsiUpperCase(SchRec.Name);
    P^.Path:=Dir;
    Lst.Add(P);
    GetPamat:=GetPamat+SizeOf(SchRec.Size)
                      +length(SchRec.Name)+18
                      +length(Dir)+18;
end;

procedure TSameForm.KillAllFiles(Lst: TList);
var i: Integer;
begin
    Lst.First;
    For i:=0 to Lst.Count-1 do Dispose(Lst[i]);
    Lst.Clear;
end;

procedure TSameForm.ScanDir(StartDir: string);
var  SearchRec: TSearchRec;
begin
    If StartDir[Length(StartDir)]<>"\" then StartDir:=StartDir+"\";
    If FindFirst(StartDir+"*.*",faAnyFile,SearchRec)=0 then begin
repeat If (SearchRec.Attr and faDirectory)<>faDirectory then AddFile(ListOfFiles,SearchRec,StartDir)
                                                               else If (SearchRec.Name<>"..")and(SearchRec.Name<>".") then ScanDir(StartDir+SearchRec.Name+"\");
until FindNext(SearchRec)<>0;
FindClose(SearchRec);
    end;
    StBar.Panels[2].Text:=" "+StartDir;
    StBar.Panels[1].Text:=" Найдено : "+IntToStr(kolFls)+" файла(ов)";
    StBar.Panels[0].Text:=" Память: "+myFileSize(GetPamat);
    Application.ProcessMessages;
end;

procedure TSameForm.ItemFindClick(Sender: TObject);
var i: Integer;
   p: PmySearchRec;
begin
    kolFls:=0;
    GetPamat:=0;
    try ScanDir(DirectoryLB.Directory);
    except Beep;
           MessageDLG("Ошибка обращения к диску !",mtWarning,[mbYes],0);
    end;
    StBar.Panels[2].Text:=" Анализ данных ...";
    ProgressBar.MinValue:=0;
    ProgressBar.MaxValue:=ListOfFiles.Count-1;
    ProgressBar.Progress:=0;
    Application.ProcessMessages;
    For i:=0 to ListOfFiles.Count-1 do begin
        p:=ListOfFiles.Items[i];
        {p^.Size}
        {p^.Name}
        {p^.Path}
        ProgressBar.Progress:=i;
        Application.ProcessMessages;
    end;
    KillAllFiles(ListOfFiles);
    ProgressBar.Progress:=0;
end;

Теперь все работает отлично. Память совсем (ну почти совсем) не потребляется. Относительно первого варианта - это "небо и земля".


 
opoloXAI   (2004-07-16 11:44) [43]

Мне только интересно, я с Dispose(Lst[i]) сделал все правилно?


 
Суслик ©   (2004-07-16 11:55) [44]


> opoloXAI   (16.07.04 11:44) [43]
> Мне только интересно, я с Dispose(Lst[i]) сделал все правилно?

Сейчас на меня будут кричать (застарелый спор), но вы сделали не верно.

Т.к. запись TmySearchRec содержит одно поле с управляемым временем жизни, т.е. типа string, то для того, чтобы был все корректно нужно, чтобы не только очисталась память из под записи, но и из под строки.
В вашем случае будет чиститься только из под записи.
надо делать так
var
 p: pmySearchRec
begin
  for ......
  begin
     p := list[i];
     dispose(p);
  end;
end;

Моя правота легко проверяется: достаточно посмотреть cpu - в вашем случае будет просто вызов freemem, в моем dispose.


 
Суслик ©   (2004-07-16 11:56) [45]


> Суслик ©   (16.07.04 11:55) [44]

чтобы понять неверность вашего подхода сделайте в конце showmessage(inttostr(allocmemsize)). При многократном выполнении операции вы увидите, что будет выводиться постоянно увеличивющееся значение.


 
Pavelkq   (2004-07-16 12:54) [46]

А сколько символов может содержать переменная стринг неопределенной длинны?


 
Суслик ©   (2004-07-16 13:03) [47]


> Pavelkq   (16.07.04 12:54) [46]

2гб если не ошибаюсь


 
Pavelkq   (2004-07-16 13:17) [48]

В Гб, не ошибаешься, а сколько это конкретно символов? 1байт = 1символ?


 
Суслик ©   (2004-07-16 13:25) [49]


> 1байт = 1символ?

смотря какая строка - ansisting или widestring


 
Pavelkq   (2004-07-16 13:54) [50]

Я про конкретный пример Path: String; Не знаю какой тут конкретно.


 
Суслик ©   (2004-07-16 14:05) [51]


> Не знаю какой тут конкретно.

здесь 1 б = 1с + накладные расходы.



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

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

Наверх




Память: 0.56 MB
Время: 0.035 c
3-1089271451
Алексей
2004-07-08 11:24
2004.08.01
JET: строка подключения к БД Fox и dBase


14-1088750364
ИМХО
2004-07-02 10:39
2004.08.01
Еще раз о Великой Отечественной


14-1089951029
Глеб
2004-07-16 08:10
2004.08.01
Сохранение изображения в 3D Studio MAX


9-1081651382
GrayFace
2004-04-11 06:43
2004.08.01
Как использовать DirectDraw или 2d OpenGL?


8-1084862377
Sapersky
2004-05-18 10:39
2004.08.01
Использование MMX в Delphi