游戏乐悠悠网游开发网

 找回密码
 立即注册
查看: 1686|回复: 0
打印 上一主题 下一主题

window 下 Unreal3 的内存管理(四

[复制链接]
  • TA的每日心情
    无聊
    2014-8-8 12:31
  • 签到天数: 37 天

    [LV.5]常住居民I

    鲜花(0) 鸡蛋(0)
    跳转到指定楼层
    楼主
    发表于 2012-2-26 11:01:12 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    // 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 最后能整除。
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    小黑屋|手机版|Archiver|Online Game Xingbarking Dev Team  

    GMT+8, 2024-11-24 03:58 , Processed in 0.116387 second(s), 33 queries .

    Powered by Discuz! X3.2 Licensed

    © 2001-2013 Comsenz Inc.

    快速回复 返回顶部 返回列表