Delphi out of memory как исправить

Можно работать через TStreamReader и TStreamWriter. При некоторых условиях скорость работы может быть больше до 3х раз, чем по-старинке с readln и writeln:

var
  s:string;
  reader:TStreamReader;
  writer:TStreamWriter;

begin
   reader:=TStreamReader.Create(OpenDialog1.FileName, TEncoding.ANSI); // Если нужна другая кодировка - сменить
   writer := TStreamWriter.Create('out.txt', false,TEncoding.ANSI); // если нужно дописать файл, ставим True вместо false
   while not reader.EndOfStream do
     begin
        s:=reader.ReadLine;
        // делаем, что нужно с s
        writer.WriteLine(s); 
     end;
   // не забываем закрыть оба файла:
   reader.Free;
   writer.Free;
end;

Если же нужно обязательно хранить все строки в памяти, стоит работать через, например, TMemoryStream или TBytesStream, но стоит помнить, что в 32-битном режиме их емкость ограничена чуть менее, чем 2 Гб, а в 64-битном режиме, если надо > 2 Гб, с ними можно нормально работать только, начиная с Delphi Tokyo, или же делать патч.

Go Up to Error and Warning Messages (Delphi)

You get this error when the RAD Studio built-in compiler runs out of memory.

This is a rare error that might occur when you build an extremely large project group of applications and libraries.

To solve this issue, do any of the following:

  • Make sure your swap file is large enough and that there is still room on your disk. See Change the size of virtual memory.
  • Configure your project group to be built externally to the IDE: Select Project > Options > Delphi Compiler and check the Use MSBuild externally to compile property.
    Note: If you want to be able to debug your app when you build with this option set, the Include remote debug symbols option should also be enabled on Project > Options > Delphi Compiler > Linking.
  • Build your project group on the command line.
  • Refactor the applications and libraries in your project group to rely more on Delphi packages. Delphi packages do not make the IDE run out of memory.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
procedure TForm9.Button1Click(Sender: TObject);
var
RusA: set of Char;
Finput,Hinput,Tinput : File;
Dialog : TOpenDialog;
StrInput: array of Byte;
Stmp,key: string;
i,j,H,len,size,sizeedit: integer;
Buff,shifr,Shifr2 : AnsiString;
ok :boolean;
begin
RusA:=['A','B','C','D','E','F','0','1','2','3','4','5','6','7','9'];
key:=edit1.text;
sizeedit:=Length(edit1.text);
for I := 1 to Sizeedit do begin
if (key[i] in RusA) then ok:=true
else ok:=false;
end;
if (ok=true) then begin
//Ищем файл
Progressbar1.Position:=0;
ShowMessage('Откройте нужный файл!');
Dialog := OpenDialog1;
if Dialog.InitialDir = '' then Dialog.InitialDir := ExtractFilePath( Application.ExeName );
if not Dialog.Execute then Exit;
if not FileExists(Dialog.FileName) then begin
MessageBox(0,'Файл не найден.','Файл не найден',MB_OK + MB_ICONWARNING + MB_APPLMODAL);
Exit;
end;
//Присваиваем файлу имя
AssignFile(Finput, Dialog.FileName);
Progressbar1.Position:=20;
Reset(Finput, 1);
Size:= FileSize(Finput);
If size<134217728 then begin  /////////(это на время пока не исправлю ошибку с размерами)
SetLength(StrInput, Size);//Задаем размер массива с размером файла
BlockRead(Finput, StrInput[0], Size);//Считываем файл в строку байтов
CloseFile(Finput);
//Представляем строку байтов в виде HEX кода
Len := Size * 3 + (Size div 16);
Progressbar1.Position:=50;
if Size mod 16 > 0 then Dec(Len);
SetLength(HexInput, Len);
H := High(StrInput);
j := 1;
for i := 0 to H do begin
STmp := IntToHex(StrInput[i], 2);
HexInput[j] := STmp[1];
HexInput[j + 1] := STmp[2];
Inc(j, 2);
if i = H then Continue;
if i mod 16 = 15 then begin
HexInput[j] := #13;  // probel
HexInput[j + 1] := #10; //konec stroki
Inc(j, 2);
end else begin
HexInput[j] := #9;    //Tab
Inc(j);
end;
end;
Progressbar1.Position:=70;
if checkbox1.Checked=true then Memo1.Text := HexInput; //чистый HEX
Progressbar1.Position:=90;
Shifr:=Viz_crypt(HexInput,Edit1.text);
if checkbox1.Checked=true then Memo2.Text:=shifr;      //кодированный HEX
Shifr2:=getbytestr(shifr);
AssignFile(hinput, Dialog.FileName+'.cry');
Rewrite(hinput, 1);
BlockWrite(hinput, Shifr2[1], Length(Shifr2));//Считываем файл в строку символов
Closefile(hinput);
end else begin
showmessage('Пожалуйста, выберите файл меньшего размера!');/////////(это на время пока не исправлю ошибку с размерами)
Progressbar1.Position:=0;
exit;
end;
end else showmessage('Пожалуйста, введите ключ содержащий только:A,B,C,D,E,F,0,1,2,3,4,5,6,7,9');
Progressbar1.Position:=100;
ShowMessage('Готово!');
end;


Re: Увеличить память для приложения (EOutOfMemory)

От:

glh

Россия

 
Дата:  15.10.14 17:33
Оценка:

16 (2)

Здравствуйте, indee, Вы писали:

I>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

I>Можно ли в Windows выделить больше памяти для выполнения приложения?

Ваше приложение съело всю доступную память?
На моей памяти я видел такое 2 раза, и оба, незадачливый

программист

кодер, грузил огромную таблицу в DevExpress Grid.

В порядке предпочтения осмелюсь предложить.
1) Перепишите логику работы.
2) Задействуйте другой менеджер памяти, с более подходящей для вас стратегией.
3) Переделайте для 64 разрядов.
4) http://bit.ly/ZE1d3S

К прочтению:
Архитектура памяти в Windows
Архитектура памяти в Windows (spin-off)
Адресное пространство под микроскопом

Manager Location
HeapAlloc-based memory manager http://cc.embarcadero.com/Item.aspx?id=22668
PSD Memory Manager (based on RecyclerMM ) http://dennishomepage.gugs-cats.dk/memoryManagerChallenge.htm
RecyclerMM http://glscene.sourceforge.net/RecyclerMM.htm
NexusDB http://www.nexusdb.com/
MultiMM http://cc.embarcadero.com/Item.aspx?id=14283
FastMM http://sourceforge.net/projects/fastmm/
FastSharemem http://www.thejobpage.com/emil/codexterity/fastsharemem.htm
ProcessMemMgr http://home.foni.net/~winter/delphi-bits/PrcMemMgr.zip
qmem http://www.torry.net/vcl/vcltools/debug/qmemory.zip, http://www.ussr.to/Russia/delphiplus/downloads/library/qmem.zip
HPMemMgr http://www.optimalcode.com/memmgr.htm, http://codecentral.borland.com/codecentral/snippets/14283.zip
SapMM https://code.google.com/p/sapmm/
scalemm http://code.google.com/p/scalemm/
SynScaleMM http://blog.synopse.info/post/2010/12/04/SynScaleMM
SafeMM http://cc.embarcadero.com/item/27241

PS. Претензии по ссылкам не принимаются, все были актуальны на момент сохранения.

Успехов!
C уважением, Алексей.
————————————————
Хороших %s не бывает — бывает не худший вариант.


Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  15.10.14 15:59
Оценка:

Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).
Можно ли в Windows выделить больше памяти для выполнения приложения?

Спасибо!


Re: Увеличить память для приложения (EOutOfMemory)

От:

RainBoy

 
Дата:  29.10.14 20:12
Оценка:

{$SETPEFLAGS $0020} // IMAGE_FILE_LARGE_ADDRESS_AWARE = $0020;

http://cc.embarcadero.com/item/24309

В моей практике реально понадобилось 1 раз, когда сторонняя DLL кушала > 1.7 Gb памяти.

… << RSDN@Home 2.2.0 alpha 5 rev. 0>>


Re: Увеличить память для приложения (EOutOfMemory)

От:

jhfrek

Россия

 
Дата:  29.10.14 20:22
Оценка:

Здравствуйте, indee, Вы писали:

I>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

если количество объектов реально большое и они реально нужны, их надо кэшировать в собственном менеджере памяти, потому как дельфийский можно действительно переполнить за счет сегментации


Re[2]: Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  30.10.14 08:48
Оценка:

Здравствуйте, jhfrek, Вы писали:

J>Здравствуйте, indee, Вы писали:


I>>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).


J>если количество объектов реально большое и они реально нужны, их надо кэшировать в собственном менеджере памяти…

Можно подробнее?
Спасибо!


Re[3]: Увеличить память для приложения (EOutOfMemory)

От:

Danchik

Украина

 
Дата:  30.10.14 10:39
Оценка:

Здравствуйте, indee, Вы писали:

I>Здравствуйте, jhfrek, Вы писали:


J>>Здравствуйте, indee, Вы писали:


I>>>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).


J>>если количество объектов реально большое и они реально нужны, их надо кэшировать в собственном менеджере памяти…


I>Можно подробнее?

I>Спасибо!

Попробуйте менеджеры памяти котрые вам описывали выше. Еще рано писать свой.


Re[3]: Увеличить память для приложения (EOutOfMemory)

От:

glh

Россия

 
Дата:  30.10.14 16:21
Оценка:

Здравствуйте, indee, Вы писали:

I>Можно подробнее?

Я бы все же начал с ответа на вопросы:
Почему? (создается так много объектов)
Зачем? (они все нужны, прямо сейчас, одновременно)

Не зря предложение изменить логику работы идет первым.

Это самый интенсивный способ.
Остальные или отодвигают проблему на потом или решают ее количественно.

Игровые миры содержат огромное количество объектов-полигонов. Однако работают.
Текстовые редакторы редактируют огромные тексты пользуясь небольшим буфером.
Во времена DOS, а там существенные ограничения на память были, 16 бит все-таки, обрабатывали массивы данных ну никак не помещавшиеся в ОЗУ, вытесняли не используемые страницы на диск.

Успехов!
C уважением, Алексей.
————————————————
Хороших %s не бывает — бывает не худший вариант.


Re[3]: Увеличить память для приложения (EOutOfMemory)

От:

jhfrek

Россия

 
Дата:  30.10.14 20:13
Оценка:

Здравствуйте, indee, Вы писали:

J>>если количество объектов реально большое и они реально нужны, их надо кэшировать в собственном менеджере памяти…

I>Можно подробнее?

к примеру

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

for i := 1 to 10000000 do
  for j := 1 to 1000000 do
    ...
      for k := 0 ro 100000 do begin
        getmem(sizeof(integer))
        ....
        freemem()
      end

меняем на array of pointer := getmem(sizeof(integer) * большое число), а вместо getmem(), freemem() пишем inc/dec (указатель на свободное место в массиве)

ЗЫ. видел код где Assign производился через последовательность object.Free; object.CreateCopy(newObject). Банальный рефакторинг сильно уменьшил нагрузку на менеджер памяти. Так что я бы сильно поанализировал, прежде чем заниматься оптимизацией менеджера.
ЗЗЫ. Еще встречал когда динамические массивы в цикле мучили SetLength(array, Length(array) + 1)…


Re: Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  16.12.14 09:25
Оценка:

Здравствуйте, indee, Вы писали:

I>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

I>Можно ли в Windows выделить больше памяти для выполнения приложения?

I>Спасибо!

OS Windows XP, 4GB RAM, Task Manager показывает, что использовано 60% памяти, приложение съело не более 250MB и Out of memory (EOutOfMemory)…
Почему не доступна для приложения оставшаяся свободная память Windows?


Re[2]: Увеличить память для приложения (EOutOfMemory)

От:

BlackEric

http://black-eric.lj.ru
Дата:  16.12.14 14:17
Оценка:

Здравствуйте, indee, Вы писали:

I>OS Windows XP, 4GB RAM, Task Manager показывает, что использовано 60% памяти, приложение съело не более 250MB и Out of memory (EOutOfMemory)…

I>Почему не доступна для приложения оставшаяся свободная память Windows?

Возможно, ему нужен большой непрерывный кусок


Re[2]: Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  17.12.14 08:17
Оценка:

Здравствуйте, glh, Вы писали:

glh>Здравствуйте, indee, Вы писали:


I>>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

I>>Можно ли в Windows выделить больше памяти для выполнения приложения?

glh>Ваше приложение съело всю доступную память?

Я был бы рад, если приложение съест всю доступную память…


Re[3]: Увеличить память для приложения (EOutOfMemory)

От:

BlackEric

http://black-eric.lj.ru
Дата:  17.12.14 09:12
Оценка:

Здравствуйте, indee, Вы писали:

I>Здравствуйте, glh, Вы писали:


glh>>Здравствуйте, indee, Вы писали:


I>>>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

I>>>Можно ли в Windows выделить больше памяти для выполнения приложения?

glh>>Ваше приложение съело всю доступную память?


I>Я был бы рад, если приложение съест всю доступную память…

Какой делфи и менеджер памяти?


Re[2]: Увеличить память для приложения (EOutOfMemory)

От:

jhfrek

Россия

 
Дата:  17.12.14 09:16
Оценка:

Здравствуйте, indee, Вы писали:

I>OS Windows XP, 4GB RAM, Task Manager показывает, что использовано 60% памяти, приложение съело не более 250MB и Out of memory (EOutOfMemory)…

I>Почему не доступна для приложения оставшаяся свободная память Windows?

попробуйте тупо прописать fastmm и посмотрите что получится


Re[2]: Увеличить память для приложения (EOutOfMemory)

От:

Dimonka

Верблюд

 
Дата:  17.12.14 12:09
Оценка:

Здравствуйте, indee, Вы писали:

I>OS Windows XP, 4GB RAM, Task Manager показывает, что использовано 60% памяти, приложение съело не более 250MB и Out of memory (EOutOfMemory)…

250 мб — это совсем не много. Дело в чём-то другом. Попробуй создать лог создания/уничтожения и посмотри что создаётся и от чего падает.


Re[4]: Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  17.12.14 12:55
Оценка:

Здравствуйте, BlackEric, Вы писали:

BE>Здравствуйте, indee, Вы писали:


I>>Здравствуйте, glh, Вы писали:


glh>>>Здравствуйте, indee, Вы писали:


I>>>>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

I>>>>Можно ли в Windows выделить больше памяти для выполнения приложения?

glh>>>Ваше приложение съело всю доступную память?


I>>Я был бы рад, если приложение съест всю доступную память…


BE>Какой делфи и менеджер памяти?

Delphi 7, менеджер памяти по умолчанию (Borland MM?)


Re[3]: Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  17.12.14 13:45
Оценка:

Здравствуйте, Dimonka, Вы писали:

D>Здравствуйте, indee, Вы писали:


I>>OS Windows XP, 4GB RAM, Task Manager показывает, что использовано 60% памяти, приложение съело не более 250MB и Out of memory (EOutOfMemory)…


D>250 мб — это совсем не много. Дело в чём-то другом. Попробуй создать лог создания/уничтожения и посмотри что создаётся и от чего падает.

Проверял, построчно проверял утечку создания/уничтожения — все не очень плохо.
Плохо то, что я не могу создать большое кол-во «жирных» обjектов.

Зачем покупать 4Gb на WinXP32, если при 1Gb все так же валится, не зависимо от объема свободной памяти.


Re[5]: Увеличить память для приложения (EOutOfMemory)

От:

BlackEric

http://black-eric.lj.ru
Дата:  17.12.14 14:34
Оценка:

Здравствуйте, indee, Вы писали:

BE>>Какой делфи и менеджер памяти?


I>Delphi 7, менеджер памяти по умолчанию (Borland MM?)

Ему нужна непрерывная память для выделения. Попробуйте использовать FastMM.
Или выделяйте при старте память с запасом, а потом работайте с этим участком


Re[4]: Увеличить память для приложения (EOutOfMemory)

От:

Dimonka

Верблюд

 
Дата:  17.12.14 15:03
Оценка:

Здравствуйте, indee, Вы писали:

I>Проверял, построчно проверял утечку создания/уничтожения — все не очень плохо.

I>Плохо то, что я не могу создать большое кол-во «жирных» обjектов.

Может тогда скажешь что за обьекты? Может другие идеи появятся как помочь?
«Жирные обьекты» можно разбивать на несколько менее жирных, либо проецировать в memory mapped files.


Re[6]: Увеличить память для приложения (EOutOfMemory)

От:

indee

 
Дата:  03.01.15 08:49
Оценка:

Здравствуйте, BlackEric, Вы писали:

BE>Здравствуйте, indee, Вы писали:


BE>>>Какой делфи и менеджер памяти?


I>>Delphi 7, менеджер памяти по умолчанию (Borland MM?)


BE>Ему нужна непрерывная память для выделения. Попробуйте использовать FastMM.

BE>Или выделяйте при старте память с запасом, а потом работайте с этим участком

Спасибо за совет!

С FastMM все работает гараздо лучше, там где приложение ело 200Мб, сейчас всего 8Мб.


Re[7]: Увеличить память для приложения (EOutOfMemory)

От:

vladislav_somov

Россия

 
Дата:  25.01.15 21:26
Оценка:

Здравствуйте, indee, Вы писали:

I>Здравствуйте, BlackEric, Вы писали:


BE>>Здравствуйте, indee, Вы писали:


BE>>>>Какой делфи и менеджер памяти?


I>>>Delphi 7, менеджер памяти по умолчанию (Borland MM?)


BE>>Ему нужна непрерывная память для выделения. Попробуйте использовать FastMM.

BE>>Или выделяйте при старте память с запасом, а потом работайте с этим участком

I>Спасибо за совет!


I>С FastMM все работает гараздо лучше, там где приложение ело 200Мб, сейчас всего 8Мб.

Я бы все же посоветовал взглянуть на архитектуру под другим углом. FastMM, в данном случае, — это «лечение симптомов», а не решение проблемы. Если при этом Вы не самостоятельно работаете активно с памятью, то, возможно, работаете, например, со стоками или с классом TStringList (возможно, неявно).


Re[2]: Увеличить память для приложения (EOutOfMemory)

От:

vladislav_somov

Россия

 
Дата:  20.02.15 20:40
Оценка:

Здравствуйте, indee, Вы писали:

I>Здравствуйте, indee, Вы писали:


I>>Программа (написанная на Delphi) создает большое количество объектов. Иногда это приводит к Out of memory (EOutOfMemory).

I>>Можно ли в Windows выделить больше памяти для выполнения приложения?

I>>Спасибо!


I>OS Windows XP, 4GB RAM, Task Manager показывает, что использовано 60% памяти, приложение съело не более 250MB и Out of memory (EOutOfMemory)…

I>Почему не доступна для приложения оставшаяся свободная память Windows?

Фрагментация памяти. FastMM спасет, но лучше все же разобраться с болезнью, а не с симптомами.

Подождите ...

Wait...

  • Переместить
  • Удалить
  • Выделить ветку

Пока на собственное сообщение не было ответов, его можно удалить.

Hey there,

I needed a code to act like a bruteforcer so I found one, but the problem is I don’t want to use TStringList, so I replaced it with array of strings and added some modifications.
The problem is when I run the code, after a certain time I get «Out Of Memory» error.

I hope someone can show me where is my error, I use FreeMem and SetLength to free the array of string each iteration.
Code is below..

Regards

function   bruteforce(astring:   string  ;substr:   string  ;  startlen: integer;
endlen: integer): LongInt; 
var   i,n,x: integer;
bi,bc,br:integer;
npw:   string  ;
counter:integer;
bhlplst: array of string;
bcluster : array of string;
bresults : array of string;
label   step1;
begin
bi := 0;
bc := 0;
br := 0;
//hlplst := TStringList.Create;    //The left column
//cluster := TStringList.Create;   //The middle section
//results := TstringList.Create;   //The combinations created
for   x := 1   to   length(substr)   do begin
//hlplst.Add(substr[x]);
SetLength(bhlplst, bi + 1);
bhlplst[bi] := substr[x];
Inc(bi);
end  ;
 
step1:
for   i := 0   to   {hlplst.Count}bi - 1   do begin
for   n := 1   to   length(astring)   do begin
//npw := hlplst.strings[i]+astring[n];
npw := bhlplst[i] +  astring[n];
//cluster.Add(npw);
 
SetLength(bcluster, bc + 1);
 
bcluster[bc] := npw;
 
Inc(bc);
 
 
if   length(npw) >= startlen   then
begin
//results.Add(npw);
//SetLength(bresults,br + 1);
//bresults[br] := npw;
//Inc(br);
Form1.Memo1.Lines.Add(npw);
end;
end  ;
end  ;
//hlplst.clear;
bi := 0;
SetLength(bhlplst, bi);
FreeMem(bhlplst);
//hlplst.addstrings(cluster);
SetLength(bhlplst, bc );
for counter := 0 to bc - 1 do
begin
bhlplst[bi] := bcluster[counter];
Inc(bi);
end;
//cluster.Clear;
bc := 0;
SetLength(bcluster, bc);
FreeMem(bcluster);
if   length(npw) + 1 <= endlen   then     goto   step1;
//hlplst.Clear;
bi := 0;
SetLength(bhlplst,bi);
FreeMem(bhlplst);
result := 0;
end  ;

Open in new window

Понравилась статья? Поделить с друзьями:
  • Как найти площадь кирпичной кладки
  • Как найти свой комментарий в обсуждениях
  • Как найти пройденный путь катера по течению
  • Как найти объем абс
  • Как найти фоторамки для фотографий