delphi.memory.할당 및 방출 ---New/Dispose, GetMem/FreeMem 및 기타 함수의 차이점은 동일

4996 단어 Delphi
나는 메모리 분배 + 방출이 기초 함수라고 추측하고 있다. 어떤 사람들은 이런 함수에 주의하지 않았거나 자세히 따지지 않았을지도 모르지만, 나는 그래도 이해하는 것이 좋다고 생각한다.
 
다음 메모리 함수를 소개하기 전에 무시할 수 없는 경우 MM의 몇 가지 과정을 설명합니다.
 1 TMemoryManager = record

 2   GetMem: function(Size: Integer): Pointer;

 3   FreeMem: function(P: Pointer): Integer;

 4   ReallocMem: function(P: Pointer; Size: Integer): Pointer;

 5 end;

 6 

 7 var

 8   MemoryManager: TMemoryManager = (

 9     GetMem: SysGetMem;

10     FreeMem: SysFreeMem;

11     ReallocMem: SysReallocMem);

 
다음은 D7 버전의 MM 함수입니다. 그 중에서 변수 Memory Manager는 MM 함수라고 합니다. 주의하십시오.
D2005-D2007 이상 버전(어느 버전인지 확인하지 않음), MM 함수는 Allocmem 및 Register Leak/UnRegister Leak 함수가 많으므로 본문과 무관하게 더 이상 말하지 않겠습니다.
제3자 MM이 인수하는 것은 바로 이 MM의 몇 가지 함수로 외장지대에 이르렀고 Sys가 앞장서는 SysGetMem, SysFreeMem, SysReallocMem은 자체 시스템이 자체적으로 가지고 있는 MM 처리이다.
 
1: New/Dispose
이 두 함수는delphi/pascal을 추정하면record/object 같은 데이터를 분배하고 메모리 블록을 방출하는 것을 알 수 있습니다.
그리고 분배와 방출은 GetMem/FreeMem 함수를 호출합니다. GetMem/FreeMem과 다른 점은 다음과 같습니다.
New () 는 GetMem 이후 initialize (x) 작업을 진행했습니다. 즉, record/object 데이터를 초기화하는 작업입니다.
initialize 함수, 시스템 단원에서 이 함수를 설명합니다. 즉, record/object에string,interface,dyncarray,variant,record,array의 필드를 포함하여 0(비우기)으로 초기화합니다.
이 단계는 매우 중요하다. 왜냐하면 GetMem이 되돌아오는 메모리 블록은 사용한 것을 반복해서 사용할 수 있고, 사용한 것은 값이 있음을 표시하기 때문이다.
값이 있는 상황에서 다시 값을 부여하면 낡은 주소에 대응하는 데이터를 먼저 비우고 무작위 주소의 데이터를 비워야 한다는 것을 나타냅니까?AV가 나오는데...
(GetMem 이후에 모든 필드를 초기화하면 오류가 발생하기 쉬운 것이 바로 이것이라고 생각하지 마세요. 상기 필드가 있는 상황에서 수동으로 초기화를 하려면 fillchar를 사용해야 합니다. 이유는 위와 같습니다. 
이와 반대되는 Dispose () 도 마찬가지입니다. 반조작, 비우기:finalize (x) 후 FreeMem을 진행하여 record/object에서
string,interface/dyncarray 필드,FreeMem을 직접 호출해서 유출되지 않습니다(leak)
 
요약:
       a: New==> GetMem(p, sizeof(TDataType)) + Initialize(p^) ==>AllocMem(sizeof(TDataType));
이것은 AllocMem과 구별된다. initialize (x) 는 바이트마다 0을 지우지 않고 일부 필드에만 0을 지우지 않는다.
           Dispose == Finalize(p^) + FreeMem(p);
대체할 함수가 없고finalize (p^) 이 동작을 줄일 수 없습니다. 그렇지 않으면leak가 있습니다.
b:record/object의 바늘 형식입니다. 이 함수를 분배하고 방출하는 것이 좋습니다.물론 레코드/object 안의 필드 생존 기간을 스스로 유지할 수도 있습니다.
c:시스템을 호출하면.Initialize/Finalize, 프롬프트:
           [Hint] Unit1.pas(43): Expression needs no Initialize/Finalize
record/object의 필드를 나타냅니다.string,interface,dyncarray,variant,record,array
즉, Initialize 또는 Finalize를 호출할 필요가 없음을 나타냅니다.
d:한 마디 더 하세요:모든 Warn/hint는 그 작용이 있습니다. 소홀히 하지 마십시오. 작은 버그가 그 안에 있을지도 모르니 그것들을 주목하거나 해치워 주십시오.
 
2: GetMem/FreeMem
GetMem/FreeMem은 MM의 분배와 메모리 블록 방출 함수입니다. 많은 것은 이와 관련이 있습니다. 이 두 함수는 분배나 방출 실패로 인해 이상을 던집니다(exception)
반면 MM에 대응하는 표준 분배와 방출 함수는 반환값 형태로 처리됩니다. 즉, 실패했습니다. 빈 값(nil)이나 0이 아닌 0만 반환됩니다.
즉, Get/FreeMem은 MM의 표준 함수에 대해 이상 봉인된 것이다.
이상 정보:
       GetMem fail => Out of memory.
분배 실패는 일반적으로 프로세스의 사용 가능한 메모리만 분배되고 메모리가 유출된 상황에서만 발생한다.
       FreeMem fail => Invalid pointer operation
FreeMem과 같은 주소를 두 번 눌렀는데 두 번째로 이 invalid pointer가 이상합니다.:)
 
3: GetMemory/FreeMemory
Get/FreeMemory와 GetMem/FreeMem은 기본적으로 같고, 유일하게 다른 것은 MM의 대응 함수의 반환값으로 되돌아오는 것이지 이상 처리를 하지 않는다는 것이다.
즉, GetMem에서 MM을 호출합니다.GetMem이 nil로 되돌아오면 이상이 있고, GetMemory는 nil로 되돌아와 호출자에게 처리합니다
FreeMem 호출 MM.FreeMem은 0 (오류 방출) 이 아닌 것으로 되돌아오면 이상하고, FreeMemory는 0 또는 0 이 아닌 것으로 되돌아와 호출자에게 처리합니다.
이 점은 매우 유용하다. 프로그램을 쓸 때 이상을 줄이거나 Get/Free 오류가 발생할 때 assert (...) 를 쓴다.프로그램을 중단하고 검사하고 디버깅하십시오.
 
4: SysGetMem/SysFreeMem
SysGetMem/SysFreeMem과 GetMemory/FreeMemory는 기본적으로 같지만 MM의 실현 함수를 직접 호출하는 것과 다르다.
MM의 관리자 포인터를 통해 점프하지 않습니다.
즉, SysGet/SysFreeMem은 시스템이 자체적으로 가지고 있는 MM 분배 방출 함수를 사용하고 제3자 MM이 가입하면 상기 세 쌍의 함수를 사용한다.
모두 제3자 MM이 인수하지만 SysGet/SysFreeMem은 호출된 이 시스템이 가지고 있는 MM 함수로 처리되며 제3자 MM과 무관하다.
 
5:기타
다른 일부 델파이 단원의 분배 방출 함수도 있지만, 기본적으로 상기 네 쌍의 함수에서 확장된 것은 설명하지 않는다
물론 API에서 확장된 분배 + 방출 함수도 있습니다. 이 열은 D시스템의 MM 확장과 무관합니다.
 
요약:
New+Dispose와 GetMem+FreeMem은 VCL 이상 메커니즘 보호를 바탕으로 하는 분배+방출 함수입니다.
GetMemory+FreeMemory와 SysGetMem+SysFreeMem은 호출자가 스스로 되돌아오는 것을 제어하여 이상하거나 잘못된 처리를 되돌릴지 결정합니다.
   
끝나다
2014.10.19 by qsl

좋은 웹페이지 즐겨찾기