7.21.2009

CE.NET Advance Memory Management

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 開始用起。

由下往上依次是:
  1. Program Code
  2. Read Only Data
  3. Read Write Data
  4. Resource
  5. 預留的 Heap 空間
  6. 預留的 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 是不是也是一樣?

4 則留言:

Non-human 提到...

基本上是以從64K 對齊(到CE 5.0都是這樣, WM6 & WM6.1 都有針對這做一些修改, 因為Feature 越來越多, DLL 就很多, 會有不夠擺的情形), 然後4K 一個page這樣(透過VirtualAllocate), 例如你的 RAM DLL 會被載到 64K對齊的位址, 如果你的DLL 只有 1K, 下一個DLL也是被放到下一個64K對齊的地方(換句話說, 一個DLL最小佔據的空間就是64K) (WM6 改成4K為單位對齊

checko 提到...

所以擺放在Virtual Address 時是以64K來對齊,然後commit physical時是以 4k 為單位囉?

Non-human 提到...

沒錯, 可以直接追 \Private\winceos\nk\kernel 下的 virmem.c 這是CE5.0 目錄結構, 我想 4.2 管理機制應該一致

checko 提到...

喔,感激感激 :)