欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Memory Management in Open Cascade

系統(tǒng) 1935 0

Open Cascade 中的內(nèi)存管理

Memory Management in Open Cascade

eryar @ 163 . com

一、 C ++中的內(nèi)存管理 Memory Management in C ++

1. 引言

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

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

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

2. 內(nèi)存分配方式

內(nèi)存分配有三種方式:

u 從靜態(tài)存儲區(qū)域分配。內(nèi)存在編譯時就已經(jīng)分配好,這塊內(nèi)存在程序的整個運行期間都存在。例如全局變量、 static 變量;

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

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

二、 Open Cascade 中的內(nèi)存管理 Memory Management in Open Cascade

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

1. 用法 Usage

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

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

        
          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 的內(nèi)存管理器來管理。

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

2. 配置內(nèi)存管理器 Configuring memory manager

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

配置方式為設(shè)置如下環(huán)境變量的值:

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

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

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

l MMGT _ NBPAGES :定義了頁面上可分配的小的內(nèi)存塊的數(shù)量,默認值為 1000

l MMGT _ THRESHOLD :定義了循環(huán)利用的而不是返回給堆的內(nèi)存塊的數(shù)量,默認值為 4000

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

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

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

l MMGT _ OPT = 0

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

3. 程序?qū)崿F(xiàn) Implementation details

Memory Management in Open Cascade

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

      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;

}
      
    

當(dāng) MMGT _ OPT 設(shè)置為 1 時,將會使用類 Standard _ MMgrOpt 來對內(nèi)存的分配與釋放進行優(yōu)化。優(yōu)化方法如下:

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

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

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

4. 利與弊 Benefits and drawbacks

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

相應(yīng)的弊端就是循環(huán)使的內(nèi)存在程序運行時不會返回給系統(tǒng)。這就可能導(dǎo)致大量的內(nèi)存消耗,甚至可能導(dǎo)致內(nèi)存泄露。為了避免這種情況,應(yīng)該在大量使內(nèi)存的操作結(jié)束后調(diào)用函數(shù) Standard :: Purge

使用 Open Cascade 的內(nèi)存管理器( Memory Manager )導(dǎo)致的所有的內(nèi)存開銷有:

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

      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 個字節(jié)(在 64 位的操作系統(tǒng)上是 8 個字節(jié))將在每個內(nèi)存塊的開始部分分配,用來保存其大小(或用來保存下一個可用的內(nèi)存塊的地址),只在 MMGT _ OPT 1 時有效。

所以不管 Open Cascade 的內(nèi)存管理器以優(yōu)化方式還是標準方式來管理內(nèi)存,內(nèi)存總的消耗都將會大一些。

?

Memory Management in Open Cascade


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 日本韩国一区二区三区 | 一区二区国产在线观看 | 亚洲高清中文字幕综合网 | 香港免费毛片 | 欧美黄视频网站 | 日本免费不卡在线一区二区三区 | 久久综合丝袜长腿丝袜 | 欧美成a人片在线观看久 | 国产精品女A片爽爽波多洁衣 | 久久精品一区二区免费播放 | 性欧美一级毛片在线播放 | 毛片性生活 | 91无限资源| 色人阁亚洲 | 成人在线免费观看网站 | 波多野结衣99 | 亚洲热久久| 亚洲人jizz日本人处 | www.伊人网| 亚洲成人精品久久久 | 麻豆md国产在线观看 | av在线国产精品 | 免费网站看av片 | 欧美日韩一区二区中文字幕 | 超碰综合 | v视界成人影院在线视频 | 偷拍在线观看视频在线观看地址 | 欧美aaa毛片免费看 日韩精品一二三区 | 日韩精品一区二区三区中文字幕 | 小明成人免费视频 | 国产精欧美一区二区三区 | 中文字幕一区二区三区四区 | 天天天天做夜夜夜夜做 | 亚洲精品午夜国产va久久成人 | 久久久久久综合一区中文字幕 | 亚洲一区二区三区久久久 | 日韩伊人网 | 91精品久久久久久久久久入口 | 九九久久精品视频 | 日本高清不卡一区久久精品 | 一级黄色片欧美 |