Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];

Вниз

Проблемы с памятью   Найти похожие ветки 

 
Sventitskiy ©   (2007-07-02 17:38) [0]

Добрый день.

У меня следующий вопрос. Имеется динамический массив DArray: array of TIntResultObjected, элементами которого являются записи:

TIntResultObjected=record              
WaveLength: real;          
Results: TList;          
end;

Элементы списка (поле Results) тоже записи вида:

TResultObjectedData=record
X,Y,Z: real;                        
Value_WaveLength: real;  
end;

Программа производит расчет и создает массив. Потом при повторении расчета массив должен уничтожаться а память должна соотв. освобождаться. Я делаю это как:

DArray:=Nil;

Но похоже что этого не достаточно, так как после нескольких расчетов Windows выдает сообщение Out of memory.

Как корректно освободить память?

С уважением,
Александр


 
авыф   (2007-07-02 17:40) [1]

SetLength(...,0)?


 
Desdechado ©   (2007-07-02 17:42) [2]

Пройтись по массиву и Results.Free для каждого элемента.


 
Loginov Dmitry ©   (2007-07-02 22:41) [3]

> TIntResultObjected=record              
> WaveLength: real;          
> Results: TList;          
> end;


Тут очевидно, уже не запись, а class напрашивается


 
Sventitskiy ©   (2007-07-03 00:50) [4]

Возможно напрашивается Class но сделано так и нет времени переделывать.
Как все-таки сделать с записью. Проход по массиву и Results.Free для каждого элемента не помогает!!!


 
Юрий Зотов ©   (2007-07-03 01:10) [5]

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


 
Германн ©   (2007-07-03 01:14) [6]


> Как все-таки сделать с записью. Проход по массиву и Results.
> Free для каждого элемента не помогает!!!

А какое Free может быть для записи?


 
icWasya ©   (2007-07-03 10:24) [7]

У вас в коде наверняка есть вот такие строки

SetLength(DArray,Length(DArray)+1);

если вызывать такой код много раз, то будет жуткая фрагментация памяти, что в конце концов приведёт к  Out of memory.
Решение - Перераспределять памать в DArray большими блоками,
Не использовать Length(DArray) для указания количества используемых элементов массива, а завести для этого специальную переменную.
например так

var
 DArray: array of TIntResultObjected;
 LenArray:Integer;

procedure AddToDArray;
begin
 Inc(LenArray);
 if LenArray>=Length(DArray) then SetLength(DArray,LenArray+100);//или сколько там
 DArray[LenArray-1].Results:=TList.Create;
end;

procedure ClearDArray;
var
 I:Integer;
begin
 for I:= 0 to LenArray-1 do;
 DArray[I].Results.Free;
 LenArray:=0;
 // SetLength(DArray,0);
end;


 
SlymRO ©   (2007-07-03 10:35) [8]

icWasya ©   (03.07.07 10:24) [7]
Не проще:
TResultObjectedData=record
 X,Y,Z:real;                        
 Value_WaveLength:real;  
end;
TIntResultObjected=record
 WaveLength: real;
 Results:array of TResultObjectedData;
end;

само собой убьется...


 
Desdechado ©   (2007-07-03 10:55) [9]

> А какое Free может быть для записи?
Results: TList;


 
Anatoly Podgoretsky ©   (2007-07-03 12:29) [10]

Как создавал TResultObjectedData=record
так и уничтожай, естественно в цикле


 
Sapersky   (2007-07-03 14:24) [11]

procedure AddToDArray;

Тогда уж так (несколько длинновато, зато универсально):

{$IFDEF DELPHI4or5}
Type
 PDynArrayTypeInfo = ^TDynArrayTypeInfo;
 TDynArrayTypeInfo = packed record
   kind: Byte;
   name: string[0];
   elSize: Longint;
   elType: ^PDynArrayTypeInfo;
   varType: Integer;
 end;

procedure DynArraySetLength(var a: Pointer; typeInfo: PDynArrayTypeInfo; dimCnt: Longint; lengthVec: PLongint);
asm
 push edi
 push esi
 push ebx
 mov esi, lengthVec
 mov ebx, ecx
@loop: // first we must push all lengthVec in the stack
 mov edi,[esi]
 push edi
 add esi, 4
 dec ebx
 jnz @loop
 mov ebx, ecx

 call system.@DynArraySetLength

 imul ebx, $04
 add esp, ebx // restoring stack (works like pop)
 pop ebx
 pop esi
 pop edi
end;
{$ENDIF}

// note: if elements are dynarrays, only references are copied
// with ref count increment (DynArrayAsg)
procedure Arr_Copy( Dst, Src : Pointer; Info: PTypeInfo; Cnt: Integer);
asm
 push Cnt
 CALL    System.@CopyArray;
//  add esp, 4 // for some reason we don"t need stack restoring
end;

// mostly the same as SetLength, but reallocates array with blocks in TList style
// Length(Arr) plays role of Capacity here,
// so you must keep used array size in separate variable (pass it to NewCount)
procedure Arr_Grow(Var Arr; TypInfo: PDynArrayTypeInfo; NewCount : Integer);
Var Len, Capacity : Integer;
begin
Assert(TypInfo.Kind = Byte(tkDynArray), "Arr_Grow: Only dynamic arrays supported");
If (Pointer(Arr) <> nil) then begin
 Len := PInteger(Integer(Arr) - SizeOf(Integer))^;
 If (NewCount <= Len) then Exit; // we fit to existing capacity, no need to grow  
 Capacity := Len * 2; // not sure this will be always best way...
 If Capacity < NewCount then Capacity := NewCount;
end else
 Capacity := NewCount; // was no array - just allocate NewCount elements

DynArraySetLength(Pointer(Arr), TypInfo, 1, @Capacity);
end;

function Arr_AddItem(Var Arr; TypInfo: PDynArrayTypeInfo; Var Count : Integer;
                    Src: PByte = nil; AtPos : Integer = -1): Pointer;
Var Dst : PByte;
   ElSize : Integer;
begin
Arr_Grow(Arr, TypInfo, Count + 1);
Inc(PByte(TypInfo), Length(TypInfo.Name)); ElSize := TypInfo.elSize;
Dst := PByte(Arr);
If (AtPos >= 0) and (AtPos < Count) then begin
 Inc(Dst, AtPos * ElSize);
 Move(Dst^, PByte( Integer(Dst) + ElSize )^, ElSize * (Count - AtPos));
 If (TypInfo.elType <> nil) then FillChar(Dst^, ElSize, 0);
end else
 Inc(Dst, Count * ElSize);
Result := Dst;
If (Src <> nil) then
 If TypInfo.elType <> nil then Arr_Copy(Dst, Src, PTypeInfo(TypInfo.elType^), 1)
                          else Move(Src^, Dst^, TypInfo.elSize);
Inc(Count);
end;

TypInfo добывается как TypeInfo(<тип массива>).



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

Форум: "Начинающим";
Текущий архив: 2007.07.29;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.046 c
15-1182954688
Andy BitOff
2007-06-27 18:31
2007.07.29
Третья версия лицензии GPL будет выпущена на этой неделе


10-1134482393
GanibalLector
2005-12-13 16:59
2007.07.29
выходные параметры в СОМ-сервере


1-1179816164
leonidus
2007-05-22 10:42
2007.07.29
Как переконвертировать Color в Hex ?


2-1183443768
tytus
2007-07-03 10:22
2007.07.29
TSocketConnection - познее связывание - - в другом потоке.


15-1183140482
qoooo
2007-06-29 22:08
2007.07.29
Книга - "Delphi 5, Руководство разработчика"





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