游戏乐悠悠网游开发网

标题: window 下 Unreal3 的内存管理(四 [打印本页]

作者: tianyalanzi    时间: 2012-2-26 11:01
标题: window 下 Unreal3 的内存管理(四
// Pick first available block and unlink it.. t7 Q$ ^8 X4 ^0 i. E5 f- r2 R
   Pool->Taken++;* `. p( u% |4 o' h; W
   checkSlow(Pool->FirstMem);, o9 m+ F9 ~* |' O
   checkSlow(Pool->FirstMem->Blocks>0);4 B  r. U) D$ |: Q8 d
   Free = (FFreeMem*)((BYTE*)Pool->FirstMem + --Pool->FirstMem->Blocks * Table->BlockSize);" {; A# F, ?  v, R* m8 w" }
   if( Pool->FirstMem->Blocks==0 )//这个memInfo已经不包含任何小块了. f# k% d! H& r8 f# J6 T8 e
   {
    Pool->FirstMem = Pool->FirstMem->Next;//用下一个memInfo' T3 @: ^7 A: H/ M
    if( !Pool->FirstMem )//如果没有下一个memInfo,证明这个pool已经满了
    {
     // Move to exhausted list.) ?. S* E8 v2 \- L. {- q
     Pool->Unlink();5 W1 A, N5 Z8 h  F  W9 k/ `
     Pool->Link( Table->ExhaustedPool );//则放到table的非空闲队列。$ V( D' y# v7 k  p
    }  g5 k6 `) X5 q, E! c/ o9 b* q. [
   }6 ^% x- I2 w" }6 O$ j+ o
   STAT(UsedPeak = Max(UsedPeak,UsedCurrent+=Table->BlockSize));
  }
  else
  {9 o: {# n# ?# n( g8 g
   // Use OS for large allocations.//如果大于一定大小, V& I+ w/ s0 m  m  R+ N
   INT AlignedSize = Align(Size,PageSize);//分配4KB对齐的,其实不对齐也无所谓,反正操作系统会分配4KB整数倍的
   Free = (FFreeMem*)VirtualAlloc( NULL, AlignedSize, MEM_COMMIT, PAGE_READWRITE );' {/ ?% Z" P' `  N
   if( !Free )
   {7 K) f; _+ d/ @  I7 |; ]* j
    OutOfMemory();5 D! F- q9 H# z, M# [4 m+ v
   }4 r! O/ J7 R) C  G* _
   checkSlow(!((SIZE_T)Free&65535));
  l% n0 T- J0 [
   // Create indirect.
   FPoolInfo*& Indirect = PoolIndirect[((DWORD)Free>>27)];6 k& ]. m. c$ Y2 e
   if( !Indirect )% t2 D- u. H6 B( p
   {
    Indirect = CreateIndirect();
   }

   // Init pool.
   FPoolInfo* Pool = &Indirect[((DWORD)Free>>16)&2047];
   Pool->Mem  = (BYTE*)Free;
   Pool->Bytes  = Size;8 r* A5 Q% I6 i+ {' l% e- k
   Pool->OsBytes = AlignedSize;
   Pool->Table  = &OsTable;0 _! H5 c7 d, i: G2 b0 C% s) x9 v
   STAT(OsPeak   = Max(OsPeak,  OsCurrent+=AlignedSize));
   STAT(UsedPeak = Max(UsedPeak,UsedCurrent+=Size));
  }
  MEM_TIME(MemTime += appSeconds());
  return Free;
}! E& g  d1 x8 ^+ x. R7 S* i3 i: {/ u
0 H3 |; |/ G( C3 \/ m; j; U
8 z1 R5 g: }& e0 N2 P* l$ H8 u) z

//释放

virtual void Free( void* Ptr )
{6 l8 S' ^$ ?' m) Q
  if( !Ptr )
  {
   return;5 ^  b% s* ~$ L% g; M8 @1 J0 w2 n: m
  }
  MEM_TIME(MemTime -= appSeconds());
  STAT(CurrentAllocs--);% [9 `2 j* M( }
9 L: A! q# h( X6 U& m  r8 ^. B* R* n
  // Windows version.$ j' G0 ^" ]. x' N( L7 t) Z
  FPoolInfo* Pool = &PoolIndirect[(DWORD)Ptr>>27][((DWORD)Ptr>>16)&2047];//寻址相应pool
  checkSlow(Pool->Bytes!=0);
  if( Pool->Table!=&OsTable )//如果是小于MAX_SIZE的pool+ Q# {6 g; r6 v, w& q
  {
   // If this pool was exhausted, move to available list.
   if( !Pool->FirstMem )//如果这个POOL是当前是已经全都分配完了,则现在有一个空闲的,这个pool就有空闲的空间,则进入TABLE的
* r; c% G$ K; V$ ~* h3 P
          //的空闲列表
   {2 z4 ]8 X! T8 s+ L" e
    Pool->Unlink();, D6 H9 Y5 {5 x# Z* ]
    Pool->Link( Pool->Table->FirstPool );# K) B- d5 U& j& n# @# j
   }

   // Free a pooled allocation. //把这个memInfo 链接到这个pool的可用的链表里面
   FFreeMem* Free  = (FFreeMem *)Ptr;
   Free->Blocks  = 1;; e0 {% x: J, ^0 C
   Free->Next   = Pool->FirstMem;
   Pool->FirstMem  = Free;
   STAT(UsedCurrent   -= Pool->Table->BlockSize);- O4 w4 Q; ^# q' _* Q
+ P; U0 e: t& R7 Z
   // Free this pool.# P' M6 X' s$ N; o
   checkSlow(Pool->Taken>=1);
   if( --Pool->Taken == 0 )//如果整个pool所有memInfo都空闲,则释放* Y$ J7 e( B( \8 y2 i8 L
   {' ?# w0 _$ D& I/ {
    // Free the OS memory.% m+ S" Z; F$ s7 j
    Pool->Unlink();//从当前所在的Table空闲列表中删除4 y, O0 F1 T& \6 m. Y/ M8 @0 m1 |
    verify( VirtualFree( Pool->Mem, 0, MEM_RELEASE )!=0 );2 i/ N6 M2 l: J
    STAT(OsCurrent -= Pool->OsBytes);7 n0 |( n; q$ ?! V) m2 E6 P
   }
  }6 x) J- F6 F6 ~* E1 V2 W6 \
  else5 [7 o8 f  C5 L8 Z3 R! A" Y
  {2 G6 T. \1 M, E: r* n, o
   // Free an OS allocation.% Y4 P  M* @# e' F# P( `
   checkSlow(!((INT)Ptr&65535));5 D- |' L( t' d# ~) H, E4 C
   STAT(UsedCurrent -= Pool->Bytes);. z: j1 T# H, t
   STAT(OsCurrent   -= Pool->OsBytes);
   verify( VirtualFree( Ptr, 0, MEM_RELEASE )!=0 );
  }
  MEM_TIME(MemTime += appSeconds());  H" u/ }# S( U
}4 l) _3 y4 N" r6 H



总结: v( R8 c) z. N2 C

这里有几个要说明的,因为分配粒度是64Kb,用32位的前16位, 所以保证索引PoolInfo的时候是唯一的,只要你利用索引的位数不大于16位都可以,但也毫无意义,因为返回的大于的位数也是0。U3是分配64KB大小每个POOL,我估计这个可能是个经验值,正好匹配那低16位。当然分配大于64K也无所谓。至于MAX_SIZE,U3分配的是32KB,这个也可能是经验值把,其实这个也无所谓的了,只要POOL分配的大小其实大于MAX_SIZE就可以,我的倾向于,每个table的blocksize 最后能整除。





欢迎光临 游戏乐悠悠网游开发网 (http://bbs.yxlyy.club/) Powered by Discuz! X3.2