Program zawiesza się przy alokowaniu dużej ilości pamięci

0

Potrzebując do programu dużych ilości pamięci napisałem taką oto procedurę, który alokuje potrzebną ilość:

var
  dane: array of byte;
  value: cardinal;
begin
  value:= 104857600; //100MB
  try
    setlength(dane,value);
  except
  end;
end;

Siedząc na sprzęcie z 512MB pamięci fizycznej i 768MB pamięci stronicowanej (win XP) z aktualnym zużyciem pamięci około 300MB zmieniałem wartość zmiennej value zaczynając od ok 1mld bajtów (prawie 1GB). Po skompilowaniu i włączeniu program albo przestawał odpowiadać, a wg Menedżera zadań Windows program otrzymywał od 120MB do 300MB pamięci w kilku próbach. Dodałem do kodu showmessage, żeby sprawdzić czy zawiesza się po wykonaniu try...except czy dopiero po zakończeniu procedury (ponieważ value jest zmienną lokalną):

  try
    setlength(dane,value);
  showmessage('udało się');
  except
  showmessage('nie udało się');

Program nie dochodził nigdy do showmessage, zamiast tego zawsze w pewnym momencie alokowania pamięci się zawieszał.
Po zmniejszeniu value do 100MB program działał bez problemów, również na 300MB nic nie wychodziło źle, jednak już przy 600MB powtórzyło się to samo co przy 1GB. Niestety nie wiem dlaczego się tak dzieje ani co można zrobić, żeby program w przypadku braku możliwości zalokowania potrzebnych ilości pamięci, zamiast się zawieszać, przekazywał o tym informację użytkownikowi.
Jakby ktoś mógł mi w tym pomóc, byłbym bardzo wdzięczny.
adakasty

0

spróbuj zrobić np. 4 dynamiczne tablice, każda po 250MB

z helpa

Following a call to SetLength, S is guaranteed to reference a unique string or array—that is, a string or array with a reference count of one. If there is not enough memory available to reallocate the variable, SetLength raises an EOutOfMemory exception.

więc jeśli było by niemożliwe utworzenie takiej tablicy to byś miał wyjątek

może TList bedzie rozwiązaniem

0

Ja zauwarzyłem że kolejne wersje delphi(ale nie zawsze) coraz to gorzej radzą sobie z dynamicznymi tablicami. Wywołanie SetLength() powoduje nie tylko zaalokowanie odpwiedniej ilości pamięci ale także szereg innych czynności. Więc ja proponował bym zrobic coś takiego


Type
  TByteArray = array of Byte;

var
  dane: PByte;
  value: cardinal;
begin
  value:= 104857600; //100MB
  try
    GetMem(dane, value);
  except
  end;

  // do elementu tablicy odwołujesz się TByteArray(dane)[Index]

  FreeMem(dane);
end;

Ten sposób w Delphi 7 działa i jest wszystko ok.

Pozdrawiam

PS.

Gdy brak pamięci to jest błąd EOutOfMemory
Mi udało sie zaalokowac 1GB przy 896 MB pamięci fizycznej + Plik stronicowania max 512 i zajetej pamięci około 512

1 użytkowników online, w tym zalogowanych: 0, gości: 1