Delphi Memory topics

first lesson:

Windows is a multitasking operating system, a task is an application (app), an application accounting for a process; a process in which, they can run multiple threads (so there is a lot of "multi-threaded programming" of the topic).



In terms of Win32 system to each process 4GB address space:
the low-end 2GB ($ 00000000 - $ 7FFFFFFF) to users dominate;
high-end 2GB ($ 80000000 - $ FFFFFFFF) reserved for system use.



To file or program into memory to work, take a look at our memory in the end how much of it.

There is a pagefile.sys file in the root directory of the system, this is our "virtual memory" (virtual memory file is in the form of the presence of)

the pagefile.sys called "virtual memory" seems inappropriate, so-called "virtual" is only relatively real physical memory (RAM) in terms of; "physical memory" on many books actually means is: RAM + virtual memory, which is all available memory.

"virtual memory" in some books also known as the "page file", "page file" or "swap file." "virtual memory" size can be set from the "control panel" in ., the default is automatically managed by the system

using the "virtual memory" is the mechanism of the system, no matter how much RAM should also use the "virtual memory."

RAM large, the system will use less "virtual memory", thereby increasing the speed; but RAM is not bigger is better, if you really put 4G of memory, the system can recognize and use of which is about 3G, 4G only because Win32 management capacity (addressability), and of course in this case to the other when Win64 different matter.



The so-called 4G systems to each program, is to 4G "virtual address table" and will never be true memory, or a notepad, a calculator would have required 8G.

This "virtual address" called in some books "virtual address", "page map" or "virtual memory address", also called "virtual memory address", the concept is easy and "virtual memory" confusion.

there 4G number (4294967296 this "virtual address" a) address (0 - $ FFFFFFFF), although each program has such a table, but they do not conflict, because these addresses are virtual systems when needed they will be mapped to specific real memory the address thus blocking the access of a process to another process.

in Win2000 previous releases, public memory with GlobalAlloc application, apply with LocalAlloc private memory; now through the "virtual address" the use of memory, the application process memory is private, now GlobalAlloc, LocalAlloc no difference, the same code is executed.

If you need a common cross-process memory space, you need to use the "memory map" and other means, these topics need to learn Learning.



Concept summary: physical memory, virtual memory, the virtual address table
function GlobalMemoryStatus can obtain their information on the acquisition TMemoryStatus structure.


// TMemoryStatus is _MEMORYSTATUS rename: 
_MEMORYSTATUS = Record 
  The dwLength: DWORD; {structural length} 
  dwMemoryLoad: DWORD; {represents an integer of memory used in proportions} 
  dwTotalPhys: DWORD; total physical memory {} 
  dwAvailPhys: DWORD; { available total physical memory} 
  dwTotalPageFile: DWORD; {virtual memory Total} 
  dwAvailPageFile: DWORD; {available total number of virtual memory} 
  dwTotalVirtual: DWORD; {total number of addresses of the virtual address table} 
  dwAvailVirtual: DWORD; {total number of addresses of the virtual address table available } End ;

Look to be a small program memory conditions:


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    Memo1: TMemo;
    procedure FormCreate(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  m: TMemoryStatus;
const
  num = 1024 * 1024;
begin
  GlobalMemoryStatus(m);
  Memo1.Clear;
  with Memo1.Lines do begin
    Add(Format('dwLength:'        + #9 + '%d', [m.dwLength]));
    Add(Format('dwMemoryLoad:'    + #9 + '%d', [m.dwMemoryLoad]));
    Add(Format('dwTotalPhys:'     + #9 + '%d', [m.dwTotalPhys div num]));
    Add(Format('dwAvailPhys:'     + #9 + '%d', [m.dwAvailPhys div num]));
    Add(Format('dwTotalPageFile:' + #9 + '%d', [m.dwTotalPageFile div num]));
    Add(Format('dwAvailPageFile:' + #9 + '%d', [m.dwAvailPageFile div num]));
    Add(Format('dwTotalVirtual:'  + #9 + '%d', [m.dwTotalVirtual div num]));
    Add(Format('dwAvailVirtual: '+ # 9 +' % D '[MkdwAvailVirtual Num]));
  Divend;
end;

end.

I am here to run renderings:


 Second lesson:

Static arrays, in the statement on the distribution of good memory, such as:


var 
  of arr1: Array [0..255] of Char; 
  arr2 is: Array [0..255] of Integer;
 the begin 
  ShowMessageFmt ( 'array size are:% d,% d', [SizeOf (arr1), SizeOf (arr2 )]); 
  {array sizes are: 512, 1024} End ;


For static array pointer, although not allocate memory at the declaration, but the pointer should be how much memory is allocated a set number of

such cases, we should allocate and release memory with New and Dispose such as:


type 
  TArr1 = Array [0..255] of Char; 
  TArr2 = Array [0..255] of Integer;
 var 
  of arr1: ^ TArr1; 
  arr2 is: ^ TArr2; the begin 
  New (of arr1); 
  New (arr2 is); 
  of arr1 ^: = 'case of Delphi blog'; 
  ShowMessageFmt ( '% S% S', [^ of arr1 [0], of arr1 ^ [. 1]]); in case of {} 
// ShowMessageFmt ( '% S% S', [of arr1 [0], arr1 [1] ]); { this can also} 
  arr2 is [Low (arr2 is ^)]: Low = (Integer); element forming a first {minimum} 
  arr2 is [High (arr2 is ^)]: = MaxInt; {element forming a first maximum value} 
  ShowMessageFmt ( '% D,% D', [arr2 is [0], arr2 is [255]]); {-2147483648, 2147483647} 
  the Dispose (of arr1); 
  the Dispose (arr2 is); End ;






// look work, and do it again in this example: type 
  TArr1 = Array [0..255] of Char; 
  TArr2 = Array [0..255] of Integer; 
  PArr1 = ^ TArr1; 
  PArr2 = ^ TArr2; var 
  of arr1: PArr1 ; 
  arr2 is: PArr2; the begin 
  New (of arr1); 
  New (arr2 is); 
  of arr1 ^: = 'case of Delphi blog'; 
  ShowMessageFmt ( '% S% S', [of arr1 [0], of arr1 [. 1]]); 
  arr2 is [Low (arr2 is ^)]: = Low (Integer); 
  arr2 is [High (arr2 is ^)]: = MaxInt; 
  ShowMessageFmt ( '% D,% D', [arr2 is [0], arr2 is [255]]); -2147483648 {,} 2147483647 
  the Dispose (of arr1); 
  the Dispose (arr2 is); End ;








To the known size of the allocated memory New should be used, the above example is related to a static array of pointers, pointer structure (record) to be mentioned later, too.

Essence New GetMem also function call, but we do not need to specify the size of the

but of a dynamic array is inappropriate, but to dynamically allocate memory array SetLength should be sufficient, such as:


var
  arr: array of Integer;
begin
  SetLength(arr, 3);

  arr[0] := Random(100);
  arr[1] := Random(100);
  arr[2] := Random(100);

  ShowMessageFmt('%d,%d,%d', [arr[0],arr[1],arr[2]]); {0,3,86}
end;


That how to allocate memory for a dynamic array of pointers? In fact, a dynamic array variable itself is a pointer, do not go around here to give it to get the pointer.

However, there is still a concept full of important, that we can put an untyped a pointer to an array of dynamic type, for example:


type 
  Tarr = Array  of Integer;
 var 
  P: the Pointer; the begin 
  GetMem (P,. 3 * the SizeOf (Integer)); {allocated to accommodate the space 3 of Integer} 
  {This Tarr size of 3 elements is the same, but conversion of datatypes} use 
  Tarr (P) [0]: = the Random (100); 
  Tarr (P) [. 1]: = the Random (100); 
  Tarr (P) [2]: = the Random (100); 
  ShowMessageFmt ( '% D,% D, D%', [Tarr (P) [0], Tarr (P) [. 1], Tarr (P) [2]]); {0,3,86} 
  FreeMem (P) ; End ;






GetMem and FreeMem used here, the allocation of untyped pointer which is more commonly used; other types of indicators that can be, but not necessarily the best solution, for example:


// Get the window title (obviously not as good as with the previously said StrAlloc better)
 var 
  P: the Pointer; the begin 
  GetMem (P, 256); 
  the GetWindowText (the Handle, P, 256); 
  the ShowMessage (the PChar (P));} {the Form1 
  FreeMem (P); End ;



It should be promoted and replaced by GetMemory FreeMemory GetMem, FreeMem, such as:


var
  p: Pointer;
begin
  p := GetMemory(256);
  GetWindowText(Handle, p, 256);
  ShowMessage(PChar(p)); {Form1}
  FreeMemory(p);
end;


: In the first summary
New is a pointer to the known size of the allocated memory;
; GetMem mainly to untyped pointer to allocate memory
to make use of GetMemory instead GetMem.

There is a AllocMem them and what difference does it make?

Will also allocate memory after AllocMem initialized (empty), GetMem is not, first verify follows:


var 
  P1, P2: the Pointer; the begin 
  P1: = AllocMem (256); 
  the ShowMessage (the PChar (P1)); {where appear empty} 
  freeMemory (P1); 
  P2: = GetMemory (256); 
  the ShowMessage (the PChar (P2) ); {some garbage data will be displayed here, the content depends on the contents of the previously assigned address} 
  freeMemory (P2); End ;




About FreeMemory and FreeMem the difference:
1, FreeMemory checks is nil then FreeMem, which is somewhat similar: Free with the Destroy;
2, there is a default parameter to specify the size of the memory to be released, it does not specify the release of all FreeMem (no need to releasing only a part of it);
.. 3, New corresponding Dispose also be used FreeMem or FreeMemory place

to make use FreeMemory to release GetMem, GetMemory AllocMem memory ReallocMem, ReallocMemory distribution,,.

ReallocMem, ReallocMemory the basis of memory has been allocated on the re-allocate memory, Talia is almost nil ReallocMemory one more than ReallocMem judgment, try to use it ReallocMemory such as:


type
  TArr = array[0..MaxListSize] of Char;
  PArr = ^TArr;
var
  arr: PArr;
  i: Integer;
begin
  arr := GetMemory(5);
  for i := 0 to 4 do arr[i] := Chr(65+i);
  ShowMessage(PChar(arr)); {ABCDE}

  arr := ReallocMemory(arr, 26);
  ShowMessage(PChar(arr)); {ABCDE}
  for i := 0 to 25 do arr[i] := Chr(65+i);
  ShowMessage(PChar(arr)); {ABCDEFGHIJKLMNOPQRSTUVWXYZ}
end;


Note that this example TArr above type, which is defined as an array large enough; this leaves enough array of possibilities, but generally not all use.
We generally only use such an array of pointers, otherwise an initialization insufficient memory and will crash.
even the use of their hands, nor can a trip to New initialization; should use GetMem, GetMemory, AllocMem, ReallocMem, ReallocMemory with the number of applications such as how much
should be noted, may also be re-allocated memory the more points, the less; if more points the greater should be able to guarantee the existence of previous data.
this concept VCL used in TList class.

If you can not accept that a large array (in fact, all right, a pointer on just how much heart we? only its pointer), this may be:


type
  TArr = array[0..0] of Char;
  PArr = ^TArr;
var
  arr: PArr;
  i: Integer;
begin
  arr := GetMemory(5);
  for i := 0 to 4 do arr[i] := Chr(65+i);
  ShowMessage(PChar(arr)); {ABCDE}

  arr := ReallocMemory(arr, 26);
  ShowMessage(PChar(arr)); {ABCDE}
  for i := 0 to 25 do arr[i] := Chr(65+i);
  ShowMessage(PChar(arr)); {ABCDEFGHIJKLMNOPQRSTUVWXYZ}
end;

 
This seemed puzzling, there is only one array elements can you do?
It should be understood: This is just one element it is of sufficient size and patterns of the starting point and the data elements of data indicating the

addition of SysGetMem, SysFreeMem, SysAllocMem, SysReallocMem four function, should be above the underlying implementation of these functions, in the case of Delphi default memory manager, we still do not use them directly.

 

Love of work, love life, love of literature

Guess you like

Origin www.cnblogs.com/h2zZhou/p/11588832.html