【转载】Ogre的内存分配策略

原文:Ogre的内存分配策略

读这个之前,强烈建议看一下Alexandrescu的modern c++的第一章关于policy技术的解释。应该是这哥们发明的,这里只是使用。

首先列出涉及到的头文件:(这几个头文件彼此之间相关性挺大的,应该一起看)

只在调试期使用:

OgreMemoryTracker.h

这个头文件中定义了MemoryTracker这个类,用来测试和调试Ogre的内存分配系统的。能跟踪内存的分配、回收、泄漏和统计信息。Ogre使用者不需要关注。

OgreAlignedAllocator.h

内存分配无非就对齐和不对齐两种,不对齐的话就不必要建立内存结构,但是对齐的话就需要按对齐的内存结构(本实现提供了与平台相同的对齐或者2的整数次方个位对齐供选择使用)。本文件就是定义了一个对齐的内存结构AlignedMemory,如果内存分配器决定使用对齐的,那么上层逻辑(比如什么时候分配,分配多少)由分配器决定,具体执行就得交给AlignedMemory这个类了。

其实这个类也就两个函数,一个allocate,一个deallocate,完成具体的分配工作。

OgreMemoryStdAlloc.h

这个类是个host类(host类就是组合使用policy的类),如果你看过modern c++的第一章就明白了。用的是policy的思想,把分配器和具体的分配策略分开,方便将分配器与不同的分配策略组合。这里说的分配器就是这里定义的host类STLAllocator。(具体的policy在OgreMemorySTLAllocator.h里定义)

OgreMemoryAllocatedObject

这个头文件定义了一个类AllocatedObject,供所有使用自定义内存分配policy来执行new和delete的类。也就是说这个类与STLAllocator类似,也是个host类,重载了new和delete。

AllocatedObject和STLAllocator的区别在于STLAllocator相当于在可以在程序的任何地方使用的malloc和free,使用者可以是主程序,可以是类,或函数等只要想要申请空间的东西,但是AllocatedObject则是对new和delete的重新定义,想要有自己的new和delete的类都应该继承这个类(你也可以自己的类里重载new 和delete,但是Ogre提供了基于policy的这个接口机制,好处在于内存分配策略可以非常方便的更改)

OgreMemorySTLAllocator.h

这个头文件定义了两个具体的policy类,就是供STLAllocato和AllocatedObjectr使用的不同内存分配策略。一个是StdAllocPolicy类(分配策略,直接简单封装malloc和free),一个是StdAlignedAllocPolicy类(分配策略,手动计算对齐之后调用malloc和free)。实际上,我们的电脑都有默认对齐,malloc也会自动对齐分配,所以除非你的对齐方法和默认不一样,否则直接使用StdAllocPolicy就好。

OgreMemoryNedAlloc.h

这个头文件也是定义供STLAllocator和AllocatedObject组装使用的内存分配policy的类:NedAllocPolicy,NedAlignedAllocPolicy。这里的ned内存分配器有个自己的主页:http://nedprod.com/programs/portable/nedmalloc/index.html,号称是最快速的内存分配器。这个policy就是对这个内存分配器的一个封装。

OgreMemoryNedPooling.h

嗯,这也是ned内存分配器的一个封装,供STLAllocator和AllocatedObject组装使用。有两个类:NedPoolingPolicy,NedAlignedPoolingPolicy,与上个的区别和联系就看人家的官网吧。我们只需要知道这是几种不同的内存分配策略而已,说白了要么是对malloc和free的重新封装,要么是自己重新定义了累心malloc和free的系统。

OgreMemoryAllocatorConfig.h

这个头文件不定义类,只做配置。配置啥呢?看其他的代码,例如Root,会public一个RootAlloc,这个RootAlloc就是一个内存分配的policy,无非是上面说的几种,但上面没叫这个的。这个头文件就干这个,用typedef把不同的Ogre对象使用的内存管理policy都定义下自己的名字,还根据选用的policy定义了OGRE_NEW等宏,也就是说,Ogre不打算让库使用者使用自己的new,malloc,delete等函数,,全部封装了。

综上,知道Ogre的内存分配系统用的policy技术(包括host和具体的policy,详见modern c++),host部分向提供了两个接口STLAllocattor、AllocatedObject,可用的内存分配策略(policy)有6种:StdAllocPolicy、StdAlignedAllocPolicy、NedAllocPolicy、NedAlignedAllocPolicy、NedPoolingPolicy、NedAlignedPoolingPolicy

搞这么大阵势,最后其实你可以直接很简单的在自己的类里重载下constructor和new之类的玩意实现,但是为啥要费这个事?这就是设计模式啦~~~~设计模式的好,是方便代码重用和修改。搭起这个架构是好,日后想要修改或增加policy易如反掌,要是你想要自己实现。那等着哭吧,每个类都得改了。

时间: 2024-08-02 15:11:04

【转载】Ogre的内存分配策略的相关文章

内存分配策略与回收策略

内存分配策略与回收策略 给对象分配内存以及回收给对象分配的内存.对象的内存分配绝大部分主要是在Java堆上,有一部分特殊的就是JIT编译器,经过JIT编译后被拆散为标量类型并间接地在栈上分配内存. 对象主要分配集中在新生代的Eden区,如果启动了本地线程分配缓冲,按照线程优先在TLAB上分配.少数分配在老年代,分配在哪里取决于当前使用的垃圾回收器组合和虚拟机中相关内存参数的设定. 新生代GC :Minor GC,发生在新生代的垃圾回收动作,非常频繁,速度很快. 老年代GC :Major GC/F

垃圾收集器与内存分配策略

①对于java虚拟机来说,垃圾收集器主要关注的内存区域是 堆和方法区. ②垃圾收集器就是要收集那些已经“死了”的对象.如果判断一个对象是否存活? 对象引用计数法 对象引用增加一个,那么相应的计数器加1,否则,减1. 优点:实现简单 缺点:不能处理对象间的循环引用.a引用b,b同时引用a. 可达性分析 如果节点到root节点可达,则证明是存活的:否则,已死.所以对于下图的o5,o6,o7虽然他们是循环引用的,但是到root节点无可达,所以已死可清除. ③垃圾回收器对于不同类型引用的回收规则 强引用

JVM总结(二):JVM的内存分配策略

这节我们总结一下JVM中的内存分配策略.目录如下: 内存分配策略 对象优先在新生代Eden分配 大对象直接进入老年代 长期存活的对象将进入老年代 动态对象年龄判定 空间分配担保 内存分配策略 Java技术体系中所提倡的自动内存管理可以归结于两个部分:给对象分配内存以及回收分配给对象的内存. 我们都知道,Java对象分配,都是在Java堆上进行分配的,虽然存在JIT编译后被拆分为标量类型并简介地在栈上进行分配.如果采用分代算法,那么新生的对象是分配在新生代的Eden区上的.如果启动了本地线程分配缓

Memcache 内存分配策略和性能(使用)状态检查

前言: 一直在使用Memcache,但是对其内部的问题,如它内存是怎么样被使用的,使用一段时间后想看看一些状态怎么样?一直都不清楚,查了又忘记,现在整理出该篇文章,方便自己查阅.本文不涉及安装.操作.有兴趣的同学可以查看之前写的文章和Google. 1:参数 memcached -h memcached 1.4.14 -p <num> TCP端口,默认为11211,可以不设置 -U <num> UDP端口,默认为11211,0为关闭 -s <file> UNIX soc

垃圾收集器以及内存分配策略

垃圾回收 垃圾回收的三个问题: 哪些内存需要回收? 什么时候回收? 如何回收? 1.哪些对象需要回收? 判断对象是否存活的办法: 引用计数算法:给对象中添加一个引用计数器,有一个地方引用就+1,引用失效就-1.只要计数器为0则对象已死. 优点:简单易实现: 缺点:无法解决对象之间相互引用的问题.(JVM也因为此种原因没有使用它) 根搜索算法: 通过选取出一个GC Roots对象,已它作为起始点,如果对象不可达,则对象已死. GC Roots对象: 虚拟机栈中引用的对象 方法区中类静态属性引用的对

Java虚拟机垃圾收集器与内存分配策略

Java虚拟机垃圾收集器与内存分配策略 概述 那些内存需要回收,什么时候回收,如何回收是GC需要完成的3件事情. 程序计数器,虚拟机栈与本地方法栈这三个区域都是线程私有的,内存的分配与回收都具有确定性,内存随着方法结束或者线程结束就回收了. java堆与方法区在运行期才知道创建那些对象,这部分内存分配是动态的,本章笔记中分配与回收的内存指的就是:java堆与方法区. 判断对象已经死了 引用计数算法:给对象添加一个引用计数器,每当有一个地方引用它,计数器+1;引用失败,计数器-1.计数器为0则改判

AGG第七课 内存分配策略

说明 AGG采用new/delete函数操作堆内存,有时候并不是最佳的选择.另一方面,STL的内存分配策略太繁琐,因此没有采用.在agg_allocator.h文件中描述目前内存分配策略: template<class T> struct allocator { static T* allocate_array(unsigned size) { return new T [size]; } static void free_array(T* v, unsigned) { delete [] v

第三章 垃圾收集器与内存分配策略

书中笔记: 也许并不会死: 要宣告回收一个对象死亡,至少要经历两次标记过程: 当可达性分析发现一个对象不可达的时候,将标记第一次并进行筛选,筛选的条件是此对象是否有必要执行finalize()方法,当对象没有覆盖finalize或者已被调用过,则虚拟机认为此对象没必要执行finalize,  如果判断有必要执行,则此对象将会被放入一个F-Queue队列中,之后会被一个优先级比较低的Finalizer线程去调用,但是并不会等待他执行完毕,因为此对象的finalize并不可靠,可能会死循环之类的,如

第三章 垃圾收集器和内存分配策略

第三章 垃圾收集器和内存分配策略 对象已死吗 引用计算方法 可达性分析算法 通过一些列的GC roots 对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径成为引用链,当一个对象到GC roots 没有任何引用链的则证明对象不可用的 虚拟机栈中的引用的对象 方法区中类静态属性引用的对象 方法去区中常量引用的对象 本地方法栈中JNI引用的对象 生存还是死亡 一次筛选,筛选是否有必要执行 finalize()方法 没有覆盖或者finalize()已经被调用过  视为没必要执行 放入一个F-Qu