1

메모리 매핑 파일을 다음과 같이 마무리 할 수 ​​있습니까?메모리 매핑 된 파일로 가상 메모리 구현

TVirtualMemoryManager = class 
public 
    function AllocMem (Size : Integer) : Pointer; 
    procedure FreeMem (Ptr : Pointer); 
end; 

메모리 매핑 파일 API 함수는 모두 오프셋을 취하기 때문에 메모리 매핑 된 파일의 빈 영역을 관리하는 방법을 알지 못합니다. 내 유일한 아이디어는 기본 메모리 관리 (다른 블록 크기에 대한 무료 목록 유지) 일종의 구현하는 것입니다. 그러나 나는 이것이 얼마나 효율적인지 알지 못합니다.

편집 : 내가 정말 희망은 (다윗이 나에게 분명히으로) 이것이다 :

나는 가상 메모리의 바이트의 연속 블록 (각 상대적으로 작은) 저장해야
IVirtualMemory = interface 
    function ReadMem (Addr : Int64) : TBytes; 
    function AllocateMem (Data : TBytes) : Int64; 
    procedure FreeMem (Addr : Int64); 
end; 

64 비트 주소를 사용하여 메모리로 다시 읽을 수 있습니다. 대부분의 경우 액세스는 읽기 전용입니다. 쓰기가 필요하다면 어쨌든 크기가 다를 것이므로 FreeMem 다음에 AllocMem을 사용할 것입니다.

이 인터페이스를 사용하여 메모리 매핑 된 파일에 대한 래퍼를 원합니다. 내부적으로 메모리 매핑 파일에 대한 핸들을 가지고 있으며 각 ReadMem 요청에 MapViewOfFile을 사용합니다. Addr 64 비트 정수는 메모리 매핑 파일에 대한 오프셋 일뿐입니다. 열린 질문은 그 주소를 할당하는 방법입니다 - 저는 현재 내가 유지하는 자유 블록 목록을 유지합니다.

+1

"가상 메모리"란 무엇입니까? 이 시스템은 이미 당신을 위해 그것을 수행합니다. –

+0

2/3/4 GB 메모리 제한을 우회하고 파일 (이 경우 페이지 파일)에 의해 백업 된 가상 메모리를 원합니다. – jpfollenius

+0

이 경우와 다른 인터페이스가 필요합니다. 주소 공간 한도를 초과하는 인터페이스가 필요하며 그렇지 않습니다. –

답변

2
  1. "는 내부적으로는 메모리 매핑 된 파일에 대한 핸들을 가지고 있으며, 각 ReadMem 요청에 MapViewOfFile을 사용하여"당신의 제안 CPU 자원 만 낭비, 이럴 수 있습니다.

  2. GetMem/FreeMem 요구 사항은 3/4 GB 장벽을 깨뜨릴 수 없습니다. 할당 된 모든 메모리는 FreeMem을 호출 할 때까지 메모리에 매핑되므로 일반 Delphi 메모리 관리자와 마찬가지로 메모리 공간이 부족합니다. 당신이 할 수있는 최선의 방법은 FastMM4을 의존하고 프로그램을 변경하여 메모리 사용을 줄이는 것입니다.

  3. IMHO 귀하의 사양을 변경/업데이트해야합니다. 예를 들어, "업데이트 된"질문은 일반적인 저장 문제와 같습니다.

원하는 것은 응용 프로그램에 3/4 GB 이상의 데이터를 할당하는 것입니다. 오픈 소스 유닛 SynBigTable에 이러한 기능을 구현했습니다. 이것은 순수 델파이의 빠르고 가벼운 NoSQL 솔루션입니다.

모든 크기의 파일 (64 비트 제한)을 생성 한 다음 요청시 각 레코드의 내용을 메모리에 매핑합니다. 가능한 경우 파일의 메모리 매핑을 사용합니다. TSynBigTable 메소드로 직접 인터페이스를 구현할 수 있습니다 : ReadMem=Get, AllocMem=Add, FreeMem=Delete. ID는 pointer과 같은 값이되고 TBytes 대신 RawByteString이 사용됩니다.

정수 ID 또는 문자열 ID를 사용하여 모든 데이터 블록에 액세스하거나 정교한 필드 레이아웃 (레코드 내부 또는 색인 및 빠른 검색 포함 메모리 내장 메타 데이터)을 사용할 수도 있습니다.

일반적인 내장 SQL 데이터베이스를 사용하십시오.예를 들어 SQLite3은 BLOB 필드를 처리 할 때 매우 뛰어나며 막대한 양의 데이터를 저장할 수 있습니다. 가장 많이 사용되는 레코드에 대한 간단한 메모리 내 캐싱 메커니즘을 사용하면 강력한 솔루션이 될 수 있습니다.

+0

아이디어는 아마도 더 이상 필요하지 않을 때 메모리를 해제하는 것일 것입니다. –

+0

@DavidHeffernan 그래서 새로운 ReadMem 메서드 인터페이스만으로는 충분하지 않습니다. 스토리지 라이브러리를 사용하면 요청에 따라 메모리를 할당 할 수 있습니다. 첫 번째 요점처럼 매핑 및 매핑 해제에는 비용이 듭니다. API는 작은 메모리 블록을 위해 설계되지 않았습니다. 예를 들어 [최소 x86 페이징은 4KB입니다] (http://en.wikipedia.org/wiki/Page_ (computer_memory)), 모든 메모리 맵에는 추가 메모리 (Windows 핸들, 추가 메모리 구조 ...)가 필요합니다. –

+0

@DavidHeffernan이 질문의 문제점은 기술 설계가 이미 고정되어 있으며 IMHO가 잘못되었다는 것입니다. 메모리 맵핑은 제안 된 OP로서 사용되어서는 안된다. 그것은 효율적이지 않을 것입니다. 따라서 원래의 소프트웨어 요구 사항을 해결하기 위해 32 비트 프로그램의 3/4 GB 메모리 제한없이 많은 수의 메모리 블록을 처리하는 다른 방향으로 나아갈 것을 제안했습니다. 정규 스토리지 엔진 (NoSQL 또는 SQL)이 필요합니다. 기존의 라이브러리에 의존하는 것이 때때로 좋은 생각과 시간 절약입니다. –