亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Memory Management in Open Cascade

系統 1857 0

Open Cascade 中的內存管理

Memory Management in Open Cascade

eryar @ 163 . com

一、 C ++中的內存管理 Memory Management in C ++

1. 引言

為了表現出多態,在 C ++中就會用到大量的指針和引用。指針所指的對象是從內存空間中借來的,當然要及時歸還。特別是指針在程序中隨心所欲地創建,因此,一個指針究竟指向哪個對象,一個對象到底被幾個指針所指向,是程序員十分關注的事情。

C ++中涉及到的內存管理問題可以歸結為兩方面:正確地掌握它和有效地使用它。好的程序員會理解這兩個問題為什么要以這樣的順序列出。因為執行得再快、體積再小的程序,如果不按所期望的方式去執行也是沒什么用處的程序。對于大多數程序員,正確地掌握意味著正確地調用內存分配和釋放函數;有效地使用意味著編寫自定義版本的內存分配和釋放函數。顯然,正確地掌握它要重要些。

C 中,只要用 malloc 分配的內存沒有用 free 釋放就會產生內存泄露。在 C ++中肇事者的名字換成了 new delete ,但是問題依然存在。當然,有了析構函數情況稍有改觀。因為析構函數為所有將被銷毀的對象提供了一個方便的調用 delete 的場所,但這同時又帶來了更多的煩惱,因為 new delete 是隱式地調用構造函數和析構函數的。而且可以在類中和類外自定義 new delete 操作符,這又帶來了復雜性,增加出錯的機會。

2. 內存分配方式

內存分配有三種方式:

u 從靜態存儲區域分配。內存在編譯時就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量、 static 變量;

u 從棧上分配。在執行函數時,函數內的局部變量的存儲單元都能在棧上創建,函數執行結束時,這些存儲單元自動被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配內存容量有限;

u 從堆上分配,亦稱動態內存分配。程序在運行時用 malloc new 申請任意多少的內存,程序員自己負責在用完時使用 free delete 來釋放內存。動態內存的生存期由我們決定,使用起來很靈活,但問題也最多。

二、 Open Cascade 中的內存管理 Memory Management in Open Cascade

在幾何建模的過程中,程序創建和刪除了大量的對象在動態內存中,也就是堆中。在這種情況下,標準 C ++的內存管理方式不是很高效,所以 Open Cascade 在包 Standard 中專門寫了個內存管理程序( Memory Manager )來對內存的分配與刪除進行管理。

1. 用法 Usage

為了在 C 代碼中使用 Open Cascade 提供的內存管理器,只需要將原來使用 malloc 的地方使用 Standard :: Allocate 來代替,原來使用 free 的地方使用 Standard :: Free 來代替。另外,原來使用 realloc 的地方使用 Standard :: Reallocate 來代替即可。

C ++中, operator new delete 都重新定義以便使用 Open Cascade 的內存管理器。定義代碼如下所示:

        
          public
        
        
          :

  
        
        
          //
        
        
           Redefined operators new and delete ensure that handles are 

  
        
        
          //
        
        
           allocated using OCC memory manager
        
        
          void
        
        * 
        
          operator
        
        
          new
        
        (size_t,
        
          void
        
        *
        
           anAddress) 

  {

    
        
        
          return
        
        
           anAddress;

  }



  
        
        
          void
        
        * 
        
          operator
        
        
          new
        
        
          (size_t size) 

  { 

    
        
        
          return
        
        
           Standard::Allocate(size); 

  }



  
        
        
          void
        
        
          operator
        
         delete(
        
          void
        
         *
        
          anAddress, size_t ) 

  { 

    
        
        
          if
        
        
           (anAddress) Standard::Free(anAddress); 

  }
        
      
View Code

上述代碼是將 operator new delete placement new 都重新定義了,這樣的類的 new delete 都將由 Open Cascade 的內存管理器來管理。

CDL extractor 為在其中所有類都采用這種方式來重新定義 operator new delete ,這樣 Open Cascade 所有的類(少數除外)都是使用 Open Cascade 的內存管理器來管理。

2. 配置內存管理器 Configuring memory manager

Open CASCADE 內存管理器可以配置,按不同的優化方式來分配內存,主要還是看需要分配內存的大小,或者不使用內存優化而直接使用 malloc free

配置方式為設置如下環境變量的值:

l MMGT _ OPT :若設置為 1 (默認值也是為 1 ),內存管理器將使用內存優化的方式來管理內存;若設置為 0 ,則內存的分配就是直接調用 C 的函數 malloc free 來對內存進行管理,此時,所有其它選項除了 MMGT _ CLEAR 外都將被忽略。若設置為 2 ,則會使用 Intel TBB 來對內存的分配進行優化,此時需要有 TBB 的庫。

l MMGT _ CLEAR :若設置為 1 (默認值也是為 1 ),分配的內存塊將被清零;若設置為 0 ,則內存塊將以分配時的值返回。

l MMGT _ CELLSIZE :定義了內存池中可分配內存塊的最大值。默認值為 200

l MMGT _ NBPAGES :定義了頁面上可分配的小的內存塊的數量,默認值為 1000

l MMGT _ THRESHOLD :定義了循環利用的而不是返回給堆的內存塊的數量,默認值為 4000

l MMGT _ MMAP :若設置為 1 (默認值也是為 1 ),大內存塊的分配將會使用操作系統的內存映射函數。若設置為 0 ,內存的分配將會直接使用 malloc 直接在堆上分配。

l MMGT _ REENTRANT :若設置為 1 (默認值為 0 ),所有調用內存優化的函數將會被保證安全,即使有多個不同的線程。當在使用內存優化管理( MMGT _ OPT = 1 )內存及多線程的程序時,這個值需要設置為 1

注:為了使用 Open Cascade 在多線程的程序中表現出更好的性能,推薦如下兩種設置方式:

l MMGT _ OPT = 0

l MMGT _ OPT = 1 and MMGT _ REENTRANT = 1

3. 程序實現 Implementation details

Memory Management in Open Cascade

Standard _ MMgrRoot 為內存管理器的抽象類,它定義了內存分配的釋放的虛函數。通過環境變量 MMGT _ OPT 來選擇不同的內存管理類,如下代碼所示:

      Standard_MMgrFactory::Standard_MMgrFactory() : myFMMgr(
      
        0
      
      
        )

{

  
      
      
        char
      
       *
      
        var
      
      
        ;

  Standard_Boolean bClear, bMMap, bReentrant;

  Standard_Integer aCellSize, aNbPages, aThreshold, bOptAlloc;



  
      
      
        //


      
        bOptAlloc   = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_OPT
      
      
        "
      
            )) ? 
      
        var
      
       : 
      
        "
      
      
        1
      
      
        "
      
      
            ); 

  bClear      
      
      = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_CLEAR
      
      
        "
      
          )) ? 
      
        var
      
       : 
      
        "
      
      
        1
      
      
        "
      
      
            );

  bMMap       
      
      = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_MMAP
      
      
        "
      
           )) ? 
      
        var
      
       : 
      
        "
      
      
        1
      
      
        "
      
      
            ); 

  aCellSize   
      
      = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_CELLSIZE
      
      
        "
      
       )) ? 
      
        var
      
       : 
      
        "
      
      
        200
      
      
        "
      
      
          ); 

  aNbPages    
      
      = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_NBPAGES
      
      
        "
      
        )) ? 
      
        var
      
       : 
      
        "
      
      
        1000
      
      
        "
      
      
         );

  aThreshold  
      
      = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_THRESHOLD
      
      
        "
      
      )) ? 
      
        var
      
       : 
      
        "
      
      
        40000
      
      
        "
      
      
        );

  bReentrant  
      
      = atoi((
      
        var
      
       = getenv(
      
        "
      
      
        MMGT_REENTRANT
      
      
        "
      
      )) ? 
      
        var
      
       : 
      
        "
      
      
        0
      
      
        "
      
      
            );

  

  
      
      
        if
      
       ( bOptAlloc == 
      
        1
      
      
         ) { 

    myFMMgr 
      
      = 
      
        new
      
      
         Standard_MMgrOpt(bClear, bMMap, aCellSize, aNbPages, aThreshold, bReentrant);



  }



  
      
      
        else
      
      
        if
      
       ( bOptAlloc == 
      
        2
      
      
         ) {

    myFMMgr 
      
      = 
      
        new
      
      
         Standard_MMgrTBBalloc(bClear);

  }

  
      
      
        else
      
      
         {

    myFMMgr 
      
      = 
      
        new
      
      
         Standard_MMgrRaw(bClear);

  }



  
      
      
        //
      
      
         Set grobal reentrant flag according to MMGT_REENTRANT environment variable
      
      
        if
      
       ( !
      
         Standard_IsReentrant )

    Standard_IsReentrant 
      
      =
      
         bReentrant;

}
      
    

MMGT _ OPT 設置為 1 時,將會使用類 Standard _ MMgrOpt 來對內存的分配與釋放進行優化。優化方法如下:

l 小型內存塊(小于 MMGT _ CELLSIZE 的內存)不是單獨分配。而是分配一個大的內存池(每個內存池的大小是 MMGT _ NBPAGES ),每個新建內存都被安排在當前的內存池中空閑的地方。若當前內存池被占滿,則分配另一個內存池。在當前的版本中,內存池不會返回給系統(直到程序結束)。然而,調用函數 Standard :: Free ()被釋放的內存塊會被 free 列表記錄,以便在下一個相同大小的內存塊分配時重新利用(循環使用)。

l 中型內存塊(大小在 MMGT _ CELLSIZE MMGT _ THRESHOLD 之間的內存塊)由 C 的函數 malloc free 直接管理。當這樣的內存塊被調用函數 Standard :: Free 釋放時,它們也像小型內存塊那樣被循環使用。與小型內存塊不同的是,被釋放的 free 列表中包含的中型內存塊可以通過函數 Standard :: Purge ,使其返回到堆中。

l 大型內存塊(大于 MMGT _ THRESHOLD 的內存塊,包含用于管理小型內存塊的內存池)的分配取決于 MMGT _ MMAP 的值:若為 0 ,這些內存塊在堆中分配;否則,將會使用操作系統的專用的管理內存映射文件的函數來分配。當使用 Standard :: Free 來釋放大型內存塊時,大型內存塊立即返回給系統。

4. 利與弊 Benefits and drawbacks

Open Cascade 使用內存管理器的最大好處就是其對小型內存塊的循環使用機制。當程序需要對大量小型內存塊進行分配與釋放時,這種機制使程序速度更快。實踐表明,使用這種方式程序的性能可以提高 50 %以上。

相應的弊端就是循環使的內存在程序運行時不會返回給系統。這就可能導致大量的內存消耗,甚至可能導致內存泄露。為了避免這種情況,應該在大量使內存的操作結束后調用函數 Standard :: Purge

使用 Open Cascade 的內存管理器( Memory Manager )導致的所有的內存開銷有:

l 分配的每個內存塊的大小都會以 8 個字節向上取整。(看其源代碼應該是以的個字節向上取整,源程序如下所示:)

      Standard_Address Standard_MMgrRaw::Allocate(
      
        const
      
      
         Standard_Size aSize)

{

  
      
      
        //
      
      
         the size is rounded up to 4 since some OCC classes

  
      
      
        //
      
      
         (e.g. TCollection_AsciiString) assume memory to be double word-aligned
      
      
        const
      
       Standard_Size aRoundSize = (aSize + 
      
        3
      
      ) & ~
      
        0x3
      
      
        ;

  
      
      
        //
      
      
         we use ?: operator instead of if() since it is faster :-)
      
      

  Standard_Address aPtr = ( myClear ? calloc(aRoundSize, 
      
        sizeof
      
      (
      
        char
      
      
        )) : malloc(aRoundSize) );



  
      
      
        if
      
       ( !
      
         aPtr )

    Standard_OutOfMemory::Raise(
      
      
        "
      
      
        Standard_MMgrRaw::Allocate(): malloc failed
      
      
        "
      
      
        );

  
      
      
        return
      
      
         aPtr;

}
      
    

l 額外的 4 個字節(在 64 位的操作系統上是 8 個字節)將在每個內存塊的開始部分分配,用來保存其大小(或用來保存下一個可用的內存塊的地址),只在 MMGT _ OPT 1 時有效。

所以不管 Open Cascade 的內存管理器以優化方式還是標準方式來管理內存,內存總的消耗都將會大一些。

?

Memory Management in Open Cascade


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 久久精品成人免费网站 | 手机在线看福利 | 日日爽天天干 | 亚洲国产精品婷婷久久久久 | 日韩欧美国产高清在线观看 | 亚洲精品日本高清中文字幕 | 亚洲欧美日韩在线一区二区三区 | 天天爱天天色天天干 | 超91视频 | 97影院秋霞国产精品 | 91精品综合久久久久m3u8 | 国产精品 第二页 | 日韩精品亚洲人成在线播放 | 国产精品免费一区二区区 | 日日撸夜夜干 | 久久久久久久尹人综合网亚洲 | 日韩精品视频一区二区三区 | 欧美爱爱小视频 | 国产伦精品一区二区 | 中国妞xxxx | 奶交性视频欧美 | 亚洲黄色a级片 | 久久久久久久国产精品影院 | 久久一本综合 | 黄色免费看网站 | 91在线亚洲精品一区 | 中文字幕日韩精品中文区 | 69日本人xxxx16—18 | 国内精品一区二区三区最新 | 久久婷婷久久一区二区三区 | 精品国产免费人成高清 | 久草国产在线观看 | 久久精品精品 | 91日韩精品天海翼在线观看 | 四虎一影院区永久精品 | 亚州精品一区二区三区 | 嘿嘿嘿视频免费网站在线观看 | 精品一区二区三区免费爱 | 国产看片视频 | 亚洲国产精品xo在线观看 | 九九热免费 |