1

저는 Windows Mobile 응용 프로그램에서 메모리 성능을 최적화했으며 VirtualAllocon Win32Windows CE 사이의 동작 차이를 경험했습니다.Windows Mobile에서의 연속적인 VirtualAlloc 동작

// Allocate 64k of memory 
BYTE *a = (BYTE*)VirtualAlloc(0,  65536, 
           MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 
// Allocate a second contiguous 64k of memory 
BYTE *b = (BYTE*)VirtualAlloc(a+65536, 65536, 
           MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE); 

BYTE *c = a + 65528; // Set a pointer near the end of the first allocation 
BOOL valid1 = !IsBadWritePtr(c, 8); // Expect TRUE 
BOOL valid2 = !IsBadWritePtr(c+8, 4088); // Expect TRUE 
BOOL valid3 = !IsBadWritePtr(c, 4096); // TRUE on Win32, FALSE on WinCE 

코드는 "C"에서 시작하는 데이터의 4096 "할당"

는 다음의 시험을 고려하십시오. Win32에서는 이것이 작동합니다. VirtualAlloc 문서에 합법적인지 또는 우연인지는 알 수 없지만이 동작을 예상하는 Google을 통해 발견 한 코드의 예가 많이 있습니다.

윈도우 CE에

5.0/5.2 내가 아무런 문제 그러나 일부 (모든) 윈도우 모바일 6 개 기기에 에서 ReadFile이없는 경우 99 %에서, "C"에서 메모리 블록을 사용하는 경우 & 의 WriteFile 오류 87 (매개 변수가 잘못되었습니다.)과 함께 실패합니다. 나는 ReadFileIsBadWritePtr 또는 그와 비슷한 것을 호출하고 false를 반환한다고 가정한다. 두 개의 ReadFile을 호출하면 모든 것이 잘 동작합니다. 물론 다른 API 호출이 실패 할 수도 있습니다.

위의 작업을 수행 할 수 있도록 VirtualAlloc에 의해 반환 된 메모리를 확장하는 방법을 찾고 있습니다. Windows CE에서 많은 양의 메모리를 확보하는 것은 각 프로세스가 32MB 만 나오고 다른 항목이로드되어 다른 문제를 일으키지 않고 많은 메모리 영역을 예약 할 수 없으므로 문제가됩니다. 공유 영역에 더 많은 양의 메모리를 예약 할 수는 있지만 다른 문제가 있습니다. VirtualAlloc은 미리 예약하지 않고 영역을 확대하거나 결합 할 수 있습니까?

는 나는 다음 예제 주어진 문제가 될 수 있습니다 의심 :

HANDLE hHeap1 = HeapCreate(0, 0, 0); // Heap defaults to 192k 
BYTE * a1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +96 bytes from start of heap 
BYTE * b1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of a1 
BYTE * c1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +16 bytes from end of b1 
BYTE * d1 = (BYTE*)HeapAlloc(hHeap1, 0, 64000); // +4528 bytes from end of c1 

HANDLE hHeap2 = HeapCreate(0, 4*1024*1024, 4*1024*1024); // 4MB Heap 
BYTE * a2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +96 bytes from start of heap 
BYTE * b2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of a2 
BYTE * c2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of b2 
BYTE * d2 = (BYTE*)HeapAlloc(hHeap2, 0, 64000); // +16 bytes from end of c2 

답변

1

아니요, 불가능합니다.

+0

답변을 수락했습니다 :-). 내 코드를 사용법 등을 기반으로 로컬 및 공유 메모리 영역에서 메모리 관리를 분할하는 곳에서 그대로 두어야합니다. 여전히 작동하지만 더 많은 코드 및 관리를 추가해야합니다. 감사합니다. – Steven

+0

흠, 그렇습니다. 더 나은 방법이없는 것은 수치 스럽습니다. 내가 가지고있는 다른 생각은 현재 해결 방법보다 더 복잡해질 것이라고 확신합니다. 누군가가 우리를 잘못 증명하는 것은 좋을 것입니다. –

1
내가 IsBadWritePtr을 신뢰하지 않을

이 참조 : 나는 그것을 시도 같은 메모리에 쓰기를 수행하고보고 생각 http://support.microsoft.com/kb/960154 을 하드웨어 예외가 발생하면 예외를 처리 한 다음 true 또는 false를 반환합니다. 그러나 일부 하드웨어는 한 페이지 만 쓰거나 다른 것을 쓰려고 시도 할 때 한 번만 예외를 발생한다고 들었습니다.

MEM_COMMIT없이 VirtualAlloc을 사용할 수 없으므로 가상 메모리 주소 만 예약하면됩니다. 그런 다음 실제로 메모리를 사용하려면 VirtualAlloc을 다시 호출하여 커밋을 수행하십시오. 이미 페이지를 예약 했으므로 페이지를 연속적으로 커밋 할 수 있어야합니다.

당신은 앞에서 예약하지 않고 그것을하고 싶다고 말하고 있습니다. 그러나 정면을 예약하는 것이 잘못된 것입니다. 예약은 실제 메모리를 사용하지 않고 가상 주소 범위를 예약하며 페이지를 커밋 할 때만 실제 메모리를 사용합니다.

+0

데모 코드에서 IsBadWritePtr을 사용하여 WinCE에서 메모리 영역을 잘못된 것으로 간주하는 방법을 보여주었습니다. 프로덕션 코드에서는 사용하지 않을 것입니다. VirtualAlloc을 사용하여 메모리 덩어리를 예약 할 때의 문제는 32MB로 제한되며 모두 예약 할 수 없다는 것입니다. 테스트 용 PDA의 경우 최대 18MB를 예약 할 수 있으며 다른 DLL은로드 할 수 없으므로 현실적으로 ~ 12MB를 하나의 청크에 예약 할 수 있습니다. 그래서 VirtualAlloc (다음 페이지를 사용할 수있는 경우)에 의해 커밋 된 메모리를 확장하고 해당 경계에서 메모리를 사용할 수 있는지 여부를 알고 싶습니다. – Steven

0

아, 그래. 이 경우 큰 메모리 영역에 대해 들어 보셨습니까, 나는 그것이 Microsoft의 해결 방법이라고 생각합니다/문제를 해결하십시오.

기본적으로 VirtualAlloc이 2MB를 초과하면 가상 메모리의 대용량 메모리 영역으로 이동하게되므로 32MB 제한을 초과 할 수 있습니다.

모든 것이 여기에 어떻게 작동하는지 꽤 좋은 토론있다 :
http://msdn.microsoft.com/en-us/library/ms836325.aspx

내가 이전 제품에 자신을 사용하고, 나를 위해 속임수를 썼는지가.

+0

공유 메모리 영역에 메모리 주소를 전달하면 부분 수정으로 내 컨트롤 외부의 코드가 마음에 들지 않습니다. 내 queston을 봅니다 (공유 영역에서 더 많은 양의 메모리를 예약 할 수는 있지만 가능합니다.) ... 대용량 메모리 영역을 사용하면 다른 문제가 해결 되기는하지만, 왜 두 개의 연속적인 VirtualAllocs가 작동하지 않는지, 그리고 VirtualAlloc을 확장하십시오. 나는 현재 대용량 메모리 영역 + 기타의 콤보를 사용하고 있지만 가능하다면 코드를 단순화하는 것을 선호한다. – Steven

관련 문제