![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Много памяти
dmk © (2014-08-30 11:19:00)Привет! Как гарантированно выделить скажем 4-10 гб оперативной памяти? Getmem AllocMem не всегда даже гигабайт выделяют. Нет памяти говорят и все, а в системе 24 Гб стоит. Нужно для обработки больших изображений.
dmk (2014-09-02 22:39:00) [1]Разобрался. Правильно так освобождать: VirtualFree(pMem, 0, MEM_RELEASE);
megavoid © (02.09.14 12:30) [15]
Заполняется нулями если стоит флаг MEM_COMMIT. Не всегда нужен.
dmk (2014-09-02 12:49:00) [2]Да просто проба пера :)
megavoid (2014-09-02 12:30:00) [3]А зачем mov [rdi], rax? Вроде VirtualAlloc делает сам: Memory allocated by this function is automatically initialized to zero, unless MEM_RESET is specified.
dmk (2014-09-02 02:06:00) [4]Работает кстати очень шустро :)
dmk (2014-09-02 02:03:00) [5]Немного разобрался. Вот пример на XE6:
Все нормально резервирует, но освобождать не торопиться.
Если несколько раз нажать кнопку, то следующий блок остается за процессом.
Как сию проблему решить? Может в VirtualFree чего не так указал?
unit MemMain64;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
Procedure ClearMem(Addr:UInt64; Size: UInt64);
asm
push rcx
push rbx
mov rax, 0
mov rdi, Addr
mov rcx, Size
shr rcx, 3
@@c:
mov [rdi], rax
add rdi, 8
loop @@c
pop rbx
pop rcx
end;
//..............................................................................
procedure TForm1.Button1Click(Sender: TObject);
var
pMem: pointer;
pSize: UInt64;
Error: integer;
msg: PWideChar;
TotalTime, eSize: extended;
StartTime, EndTime: DWord;
begin
self.Button1.Enabled := false;
pSize := UInt64(1024 * 1024 * 1024) * Random(10); //Гб
eSize := pSize / 1024 / 1024 / 1024;
pMem := VirtualAlloc(nil, pSize, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if pMem = nil then
begin
Error := GetLastError();
raise Exception.Create('Error Message: ' + IntToStr(Error));
end;
Memo1.Lines.Clear;
msg := PChar('Зарезервировано памяти: ' + FloatToStrF(eSize, ffNumber, 18, 2 ) + ' Гб');
Memo1.Lines.Add(msg);
//...
Memo1.Lines.Add('Память заполняется нулями ...');
StartTime := GetTickCount;
ClearMem(UInt64(pMem), pSize);
EndTime := GetTickCount;
TotalTime := (EndTime - StartTime) / 1000;
msg := PChar('Очищено ' + FloatToStrF(eSize, ffNumber, 18, 2 ) + ' Гб за ' + FloatToStrF(TotalTime, ffNumber, 18, 2) + ' сек');
Memo1.Lines.Add(msg);
//...
VirtualFree(pMem, pSize, MEM_RELEASE or MEM_DECOMMIT);
self.Button1.Enabled := true;
end;
end.
Rouse__ (2014-09-02 01:16:00) [6]Удалено модератором
dmk (2014-09-02 00:41:00) [7]>никто не будет грузить в память битмапину в 4 гигабайта в память целиком
А надо!!! Памяти полно. Фотошоп же грузит. Жрет память много и не свопит на винт.
Rouse_ (2014-09-01 21:58:00) [8]
> dmk © (30.08.14 11:19)
> Привет! Как гарантированно выделить скажем 4-10 гб оперативной
> памяти?
Гарантированно - никак. Память всегда фрагметированна, поэтому даже под 64 битами никто не может гарантировать в выделении последовательно идущего пула страниц.
Далее - может таки речь идет не о физической, а о виртуальной памяти? В этом случае все немного мягче проходит.
Ну а по поводу обработки изображений - никто не будет грузить в память битмапину в 4 гигабайта в память целиком. Зачем, если зная ее формат, мы можем работать с ней по кусочкам?
junglecat (2014-09-01 19:51:00) [9]> А может надо приложение как 64 бита компилировать?
ясен пень, указатель в 32-бит всяко больше 4Гб не адресует
MBo (2014-09-01 18:34:00) [10]>Как он это делает?
полосками
>А может надо приложение как 64 бита компилировать?
Если использовать большие куски памяти - то да, об этом в [2] сказали.
dmk (2014-09-01 18:03:00) [11]Photoshop CC открывает 4 Гб файл за 7-8 секунд. Как он это делает? Я даже гигабайт не могу выделить, а читалка тифов у меня поддерживает тифы любого размера. FSize 64 битный.
А может надо приложение как 64 бита компилировать?
dmk (2014-09-01 17:52:00) [12]Не выходит каменный цветок.
FSize := FScLen * FHeight + (FScLen * 4);
FMemEntry := VirtualAlloc(nil, FSize, MEM_RESERVE, PAGE_READWRITE);
FMemEntry даже на файле больше 900 Мб уже всегда nil. Последняя системная ошибка #8. EOutOfMemory.
megavoid (2014-08-30 15:49:00) [13]Ну ээ, там NativeInt, ну вот можно так, биттэ:
{$APPTYPE CONSOLE}
type NativeInt = Int64;
var
i: NativeInt;
begin
i := 1024 * 1024 * 1024;
i := i * 26;
AllocMem(i);
readln;
end.
http://i66.fastpic.ru/big/2014/0830/3d/9bdf2ac267d2588f7a14e4e2d940a33d.png
junglecat (2014-08-30 14:36:00) [14]512 * 3 * 1024 * 1024 = ~1.6G
а dmk 4 надо
megavoid (2014-08-30 14:30:00) [15]Странно...
{$APPTYPE CONSOLE}
begin
AllocMem(512 * 3 * 1024 * 1024);
readln;
end.
Process explorer Руссиновича показывает 1576576kb private bytes, 2252kb working set, то есть выделило-таки.
Игорь Шевченко (2014-08-30 13:03:00) [16]"4-10 Гб" можно выделить в 64-битном приложении.
junglecat (2014-08-30 12:35:00) [17]VirtualAlloc