日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【转载】ogre内存管理

發布時間:2024/9/5 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【转载】ogre内存管理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文:ogre內存管理

OGRE內存分配策略相關文件及簡述

?

OGRE提供了自己的內存分配策略,甚至為STL容器提供了新的分配策略,相關文件及簡述如下:

OgreMemoryAllocatedObject.h? OgreMemoryAllocatedObject.cpp

// 所有使用Ogre內存分配器的類的父類

?

OgreMemoryAllocatorConfig.h

//?配置內存分配相關規則

?

OgreMemoryNedAlloc.h? OgreMemoryNedAlloc.cpp

//?使用nedalloc庫,定義了類NedAllocPolicy、NedAlignedAllocPolicy

?

OgreMemoryNedPooling.h? OgreMemoryNedPooling.cpp

//?使用nedalloc庫,定義了類NedPoolingPolicy、NedPoolingAlignedPolicy

?

OgreMemoryStdAlloc.h

//?定義了類StdAllocPolicy、StdAlignedAllocPolicy

//?只是對malloc/free的簡單包裝

?

OgreMemorySTLAllocator.h

//?為STL容器提供的分配器

?

OgreMemoryTracker.h? OgreMemoryTracker.cpp

//?用于跟蹤內存的分配和釋放,并統計內存的使用和泄漏情況

//?*為避免循環引用,OgreMemoryTracker.h頭文件必須在OgrePrerequisites.h引用后引用*

?

OgreAlignedAllocator.h? OgreAlignedAllocator.cpp

//?提供對齊內存分配函數

?

對于OGRE中STL容器的內存分配策略的簡述:

?

以下是摘自OgrePrerequisites.h的代碼:

template?<typename?T,?typename?A?=?STLAllocator<T,?GeneralAllocPolicy> >

struct?vector

{

#if?OGRE_CONTAINERS_USE_CUSTOM_MEMORY_ALLOCATOR

???? typedef?typename?std::vector<T,?A>?type;???

#else

???? typedef?typename?std::vector<T>?type;???

#endif

};

如上所示,OGRE對STL容器進行了簡單的包裝,使其默認使用OGRE提供了內存分配策略GeneralAllocPolicy。在

OgreMemoryAllocatorConfig.h頭文件中,能夠容易找到GeneralAllocPolicy的定義。這樣,在使用STL容器時須加“::type”,如Ogre::vector<T>::type,或者照舊使用STL本身的內存分配策略,如std::vector<T>。如需要改變STL容器使用的內存策略,則可以按如下方式使用,Ogre::vector<T,STLAllocator<T,CustomPolicy>>::type,其中CustomPolicy為用戶指定的內存策略。

?

?

?

OGRE的內存策略配置及如何自定義內存策略

?

OGRE的內存策略配置

OGRE中默認所有類型使用一致的內存分配策略,并在編譯時便決定。在OgreMemoryAllocatorConfig.h文件中由OGRE_MEMORY_ALLOCATOR宏選擇相應的內存策略。

?

OGRE提供了如下三種內存策略:

??? NedAllocPolicy(NedAlignedAllocPolicy)

??? NedPoolingPolicy(NedPoolingAlignedPolicy)

??? StdAllocPolicy(StdAlignedAllocPolicy)

?

在OgreConfig.h中定義有

??? #define OGRE_MEMORY_ALLOCATOR_STD 1

??? #define OGRE_MEMORY_ALLOCATOR_NED 2

??? #define OGRE_MEMORY_ALLOCATOR_NEDPOOLING 4

?

在OgreBuildSettings.h中定義有

??? #define OGRE_MEMORY_ALLOCATOR 4

即OGRE默認使用的內存分配策略為NedPoolingPolicy。

***?OgreMemoryAllocatorConfig.h文件中定義MemoryCategory枚舉類型,以支持不同目的使用不同的內存分配方式,但需用戶自己實現。

?

?

如何自定義內存分配策略

(假定類名為CustomAllocPolicy,對齊類為CustomAlignAllocPolicy):

1.?在CustomAllocPolicy和CustomAlignAllocPolicy中至少實現如下三個靜態函數:

//分配內存

static inline void* allocateBytes(size_t count, const char* file = 0, int line = 0, const char* func = 0);

//釋放內存

static inline void deallocateBytes(void* ptr);

//獲取一次性分配的最大分配數量

static inline size_t getMaxAllocationSize();

2.?在OgreConfig.h頭文件中添加相應宏定義

如??#define?OGRE_MEMORY_ALLOCATOR_CUSTOM?5

3.?在OgreMemoryAllocatorConfig.h頭文件中添加代碼行,如

#elif OGRE_MEMORY_ALLOCATOR ==?OGRE_MEMORY_ALLOCATOR_CUSTOM

# include "OgreMemoryCustomAlloc.h"? //CustomAllocPolicy類所在頭文件

namespace Ogre

{

template <MemoryCategory Cat> class CategorisedAllocPolicy : public?CustomAllocPolicy{};

template <MemoryCategory Cat, size_t align = 0> class CategorisedAlignAllocPolicy : public?CustomAlignAllocPolicy<align>{};

}

4.?最后在OgreBuildSettings.h中改變定義

#define OGRE_MEMORY_ALLOCATOR?5?


?

?

?

如何在程序中使用OGRE提供的內存策略

要使用OGRE提供的內存策略(或自定義的內存策略)主要有兩種方式:

1.?繼承AllocatedObject類

2.?使用OgreMemoryAllocatorConfig.h頭文件中定義的內存操作宏

?

?

繼承AllocatedObject類

AllocatedObject類中重載了new、new[]、delete及delete[]等操作符,所以若要A類使用Ogre提供的或自定義的內存策略,只需繼承AllocatedObject類即可。AllocatedObject類以模板的形式支持各種內存分配策略。在OgreMemoryAllocatorConfig.h頭文件中對各種模板的AllocatedObject類進行了“重命名”,例如:

typedef?CategorisedAllocPolicy<Ogre::MEMCATEGORY_GENERAL>?GeneralAllocPolicy;

typedef?AllocatedObject<GeneralAllocPolicy>?GeneralAllocatedObject;

typedef?GeneralAllocatedObject? ArchiveAlloc;

typedef?GeneralAllocatedObject??ConfigAlloc;

所以在繼承使用AllocatedObject類時,可考慮使用OgreMemoryAllocatorConfig.h頭文件中的宏定義。例如:

(舉例多取自OGRE源碼,一般都標注了其文件名)

class?_OgreExport?ConfigFile?:?public?ConfigAlloc?//OgreConfigFile.h

class?_OgreExport?ArchiveManager?:?public?Singleton<ArchiveManager>,?public?ArchiveAlloc? //?OgreArchiveManager.h

而為了統一形式,在OgreMemoryAllocatorConfig.h頭文件中為繼承自AllocatedObject的類定義如下兩個宏:

#define?OGRE_NEW?new

#define?OGRE_DELETE?delete

因此在使用時,形式如下

ArchiveManager*?mArchiveManager?=?OGRE_NEW?ArchiveManager();

?

?

使用內存操作宏

除了繼承使用AllocatedObject類之外,對于C++中的原始類型(int, double等),或者來自外部庫的不能更改的類型,或者某些原因而不能繼承AllocatedObject的類型來說,如果要對它們使用Ogre自定義內存策略,則可以使用OgreMemoryAllocatorConfig.h頭文件中定義的內存操作宏:

?

以下三個宏用于分配原始內存,只是分配相應大小的內存,并不進行初始化:

OGRE_MALLOC(bytes,?category)

???????-- 分配bytes大小的內存

OGRE_ALLOC_T(T,?count,?category)

???????-- 分配sizeof(T) * count大小的內存

OGRE_FREE(ptr,?category)

?????????-- 與上述兩個配對使用,釋放ptr指向的內存

?

以下四個宏分配相應內存并進行初始化:

OGRE_NEW_T(T,?category)

??????? -- 分配sizeof(T)大小的內存,并調用T的構造函數

OGRE_NEW_ARRAY_T(T,?count,?category)

????????-- 分配sizeof(T) * count大小的內存,并對count個T類型實例依次初始化

OGRE_DELETE_T(ptr,?T,?category)

????????–?與OGRE_NEW_T?配對使用,調用T的析構函數,釋放相應內存

OGRE_DELETE_ARRAY_T(ptr,?T,?count,?category)

????????--與OGRE_NEW_ARRAY_T配對使用,對count個T類型實例依次調用其析構函數,釋放相應內存

?

舉例:

//?OgreTexture.cpp

void*?pixData?=?OGRE_MALLOC(dataSize,?Ogre::MEMCATEGORY_GENERAL);

//?OgreAxisAlignedBox.h

Vector3*?mpCorners?=?OGRE_ALLOC_T(Vector3, 8,?MEMCATEGORY_SCENE_CONTROL);

OGRE_FREE(mpCorners,?MEMCATEGORY_SCENE_CONTROL);

//?OgreAnimationState.cpp

BoneBlendMask*?mBlendMask?=?OGRE_NEW_T(BoneBlendMask,?MEMCATEGORY_ANIMATION)(blendMaskSizeHint);

OGRE_DELETE_T(mBlendMask,?BoneBlendMask,?MEMCATEGORY_ANIMATION);

//?OgreBspLevel.cpp

Brush?*?mBrushes?=?OGRE_NEW_ARRAY_T(BspNode::Brush,?mNumBrushes,?MEMCATEGORY_GEOMETRY);

OGRE_DELETE_ARRAY_T(mBrushes,?Brush, (size_t)mNumBrushes,?MEMCATEGORY_GEOMETRY);

?

對于以上7個內存操作宏分別有與其對應的對齊方式的宏定義,如OGRE_MALLOC_SIMD、OGRE_MALLOC_ALIGN、OGRE_ALLOC_T_SIMD、OGRE_NEW_T_ALIGN、OGRE_DELETE_ARRAY_T_ALIGN?等等。

***使用這些宏時,如果類型T本身繼承于AllocatedObject,對程序本身也不會產生什么壞的影響,除了顯得多此一舉。

?

Ogre提供的內存分配/釋放跟蹤器

在Ogre自己提供的NedAllocPolicy(NedAlignedAllocPolicy)、NedPoolingPolicy(NedPoolingAlignedPolicy)、StdAllocPolicy(StdAlignedAllocPolicy)三種內存分配策略中,都包含了分配/釋放跟蹤功能,如需在自定義的分配策略中添加跟蹤功能,照搬即可。該功能由MemoryTracker類實現,它統計內存的分配和釋放情況,以及內存分配語句所在文件名、行號和函數名。默認在程序結束時將統計信息輸出到終端,并保存于OgreLeaks.log文件,也可通過成員函數setReportToStdOut(bool rep)和setReportFileName(const std::string& name)設置輸出方式。

跟蹤器的使用方式都在分配策略中完成,無需在它處額外操作。唯一需要設置的就是跟蹤器開關的打開與關閉

在OgrePrerequisites.h文件中有如下宏定義

#if?OGRE_DEBUG_MODE

#if?OGRE_MEMORY_TRACKER_DEBUG_MODE

#define OGRE_MEMORY_TRACKER 1

#else

#define?OGRE_MEMORY_TRACKER?0

#endif

#else

#if OGRE_MEMORY_TRACKER_RELEASE_MODE

#define OGRE_MEMORY_TRACKER 1

#else

#define OGRE_MEMORY_TRACKER 0

#endif

#endif

即,OGRE_MEMORY_TRACKER宏開關取決于OGRE_MEMORY_TRACKER_DEBUG_MODE?或OGRE_MEMORY_TRACKER_RELEASE_MODE。而在OgreBuildSettings.h中定義有

#define?OGRE_MEMORY_TRACKER_DEBUG_MODE?0

#define?OGRE_MEMORY_TRACKER_RELEASE_MODE?0

即默認是關閉跟蹤器的,如果需要在DEBUG版下打開跟蹤器,只需要將OGRE_MEMORY_TRACKER_DEBUG_MODE設置為1。而根據OgreMemoryAllocatorConfig.h文件中內存操作宏的設置():

#if?OGRE_DEBUG_MODE??? //語句1

…//詳見源文件

#else?// !OGRE_DEBUG_MODE

#endif?// OGRE_DEBUG_MODE

即便是打開了OGRE_MEMORY_TRACKER_RELEASE_MODE宏,跟蹤器也不能記錄內存分配語句所在文件名、行號和函數名,即不能正常工作。如果需要在Release版下正常開啟跟蹤器功能,建議將語句1“#if OGRE_DEBUG_MODE”改為“#if OGRE_MEMORY_TRACKER”。

?

?

舉例:

對于如下代碼

#include?<string>

#include?<OgreRoot.h>

#include?<OgreMemoryAllocatorConfig.h>

#include?<OgreArchiveManager.h>

?

using std::string;

int?main()

{

{

??? int?*pi?=?OGRE_NEW_T(int,?Ogre::MEMCATEGORY_GENERAL)(50);

??? OGRE_FREE(pi,?Ogre::MEMCATEGORY_GENERAL);?//釋放

?

????double?*pd?=?OGRE_NEW_ARRAY_T(double, 5,?Ogre::MEMCATEGORY_GENERAL);

????OGRE_FREE(pd,?Ogre::MEMCATEGORY_GENERAL);?//釋放

?

????string?*ps?=??OGRE_NEW_T(string,?Ogre::MEMCATEGORY_GENERAL)("hello");

????OGRE_DELETE_T(ps,?string,?Ogre::MEMCATEGORY_GENERAL);?//釋放

}

{

????Ogre::ArchiveManager*?mArchiveManager?=?OGRE_NEW?Ogre::ArchiveManager();

????OGRE_DELETE?mArchiveManager;?//釋放

}

return?0;

}

現開啟跟蹤器宏開關,即將OGRE_MEMORY_TRACKER_DEBUG_MODE?和?OGRE_MEMORY_TRACKER_RELEASE_MODE?都置為1(須重新編譯)。該代碼正確釋放了所有內存,不存在內存泄漏。如果將代碼中釋放內存的語句全部注釋掉,則在Debug版下生成的OgreLeaks.log文件的內容為:

Ogre Memory: Detected memory leaks !!!

Ogre Memory: (6) Allocation(s) with total 244 bytes.

Ogre Memory: Dumping allocations ->

e:\vs project\ogretest\testmain.cpp(12) : {4 bytes} function: main

e:\vs project\ogretest\testmain.cpp(15) : {40 bytes} function: main

e:\vs project\ogretest\testmain.cpp(25) : {64 bytes} function: main

(unknown source):(0) : {52 bytes} function:

(unknown source):(0) : {52 bytes} function:

e:\vs project\ogretest\testmain.cpp(18) : {32 bytes} function: main

在Release版下生成的OgreLeaks.log文件的內容為:

Ogre Memory: Detected memory leaks !!!

Ogre Memory: (8) Allocation(s) with total 248 bytes.

Ogre Memory: Dumping allocations ->

(unknown source):(0) : {48 bytes} function:

(unknown source):(0) : {28 bytes} function:

(unknown source):(0) : {4 bytes} function:

(unknown source):(0) : {4 bytes} function:

(unknown source):(0) : {4 bytes} function:

(unknown source):(0) : {72 bytes} function:

(unknown source):(0) : {40 bytes} function:

(unknown source):(0) : {48 bytes} function:

可以看出在Debug版下,跟蹤器正常工作,順利的檢測出全部四處內存泄漏,而在Release版下則不能正常工作。將“#if OGRE_DEBUG_MODE”改為“#if OGRE_MEMORY_TRACKER”后,重新在Release版下測試,跟蹤器便能正常工作,生成的OgreLeaks.log的內容為:

Ogre Memory: Detected memory leaks !!!

Ogre Memory: (8) Allocation(s) with total 248 bytes.

Ogre Memory: Dumping allocations ->

(unknown source):(0) : {48 bytes} function:

.\TestMain.cpp(18) : {28 bytes} function: main

.\TestMain.cpp(12) : {4 bytes} function: main

(unknown source):(0) : {4 bytes} function:

(unknown source):(0) : {4 bytes} function:

.\TestMain.cpp(25) : {72 bytes} function: main

.\TestMain.cpp(15) : {40 bytes} function: main

(unknown source):(0) : {48 bytes} function:

?

?

P.S.

1. 測試代碼中,對int和double類型使用的是OGRE_NEW_T?和?OGRE_FREE?來分別分配和釋放內存,而并非前文所說的OGRE_DELETE_T,原因是因為對于int,double等基本類型來說,是沒有析構函數的,而OGRE_DELETE_T宏是要調用相應析構函數的。

2. 測試代碼中,若將using std::string;注釋掉,并將相應string類型測試語句換為如下兩句:

std::string?*ps2?=?OGRE_NEW_T(std::string,?Ogre::MEMCATEGORY_GENERAL)("world");

OGRE_DELETE_T(ps2,?basic_string,?Ogre::MEMCATEGORY_GENERAL);

其中basic_string 不能是string 或 std::string !!!? 同樣是因為OGRE_DELETE_T宏要調用basic_string類的析構函數。類似情況還有在使用std::fostream,std::fistream等等時。

轉載于:https://www.cnblogs.com/zhehan54/p/5656911.html

總結

以上是生活随笔為你收集整理的【转载】ogre内存管理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。