MSDN : CE.NET Advance Memory Management
大概說明空間的利用方式記憶體管理就是管理記憶體位址空間 (memory address)。
32 bit 有 4G 的 address。
CE分成兩半來用,High-half 給 OS,Low-half給 Process。
Address 決定了,並不會立刻佔用phyical memory,直到這個Address的內容真得被利用到,才會真的把phyical memory mapping過來 (稱為 commit)。
CE 使用記憶體位址的規則是:
每個Process 有 32M 的 address 可以用。 但是要從 0x10000 開始用起。
由下往上依次是:
- Program Code
- Read Only Data
- Read Write Data
- Resource
- 預留的 Heap 空間
- 預留的 Stack 空間
剩下的就是 Free Space 和 RAM-Base DLL 用。
RAM Base DLL 會從 32M 開始往下 Load。
=> 所以 Free Space 是被 Process Code, DATA, STACK 和 RAM-DLL 夾著。
process 在執行過程中如果create seperate heap或call VirtualAlloc 會接在剛剛"預留的STACK空間"上面開始,找第一個符合的位址區。
接著講 VirtualAlloc 這個API.是以 1k 或 4k 為 alloc 的單位。同時會對齊 64k。 <== 這個點問題,應該要怎樣"以4k 為單位,而且對齊 64k? 對齊 64k 不就是以 64k 為單位?
所以下面的code在CE里會fail:
for(i=0;i<512;i++)
pMem[i] = VirtualAlloc(0,PAGE_SIZE, MEM_RESERVE | MEM_COMMIT, PAGER_READWRITE);
因為這樣實際上 會alloc 掉的記憶體(Address space and physical memory) 是 512 * 64k Byte.
超過 32M.
=>雖然你只需要 512 * 4k Byte
所以要利用 Allocate Address 和 Commite Physical Memory 兩段式動作的方式來作:
pBase = VirtualAlloc (0, 512 * PAGE_SIZE, MEM_RESERVE, PAGE_READWRITE);
for(i=0;i<512;i++)
pMem[i] = VirtualAlloc(pBase+(i*PAGE_SIZE),PAGE_SIZE, MEM_COMMIT, PAGE_READWRITE);
這樣就只會用掉 512*4k的位置空間了。(同時又commit到實際記憶體)
接下來說明Load DLL 的記憶體使用情形已經知道RAM-DLL 是從每個process的32M邊界往前(下)使用。
除此之外,所謂DLL,就是有"共用"的特性。所以有可以一個DLL被2個 process使用。
因為CE的同一個DLL在不同的Process中需要在相同的Virtual Address (why?)。
所以在load DLL的時候,必須考慮到避開其他process 的 DLL 已經使用的位址。
一個process只有32M已經很慘了,DLL還要考慮自己不用的DLL要避開!!
Process Load A, B DLL -- Memory = A.B
Process Load A, C DLL -- Memory = A.(B).C
Process Load A, D DLL -- Memory = A.(B).(C).D
其中( )的部份在該process看來是空下來的部份
CE 5.0 是不是也是一樣?