- 浏览: 109075 次
- 性别:
- 来自: 昆明
文章分类
- 全部博客 (151)
- 120D02 (5)
- 直升机 (1)
- 我的技术资料收集 (82)
- 的技术资料收集 (4)
- .NET Solution (2)
- ASP.NET (1)
- Linq to sql (1)
- 数据库技术(MS SQL) (2)
- 架构/设计 (1)
- 敏捷/持续集成 (1)
- C#.NET开发 (1)
- Matlab开发 (1)
- WinForm开发 (1)
- 开源技术 (1)
- jQuery (1)
- 我的博文 (4)
- js (2)
- android (2)
- 9. 读书笔记 (1)
- CSS3 (1)
- HTML5 (1)
- JavaScript (5)
- 移动开发 (2)
- 编程心得 (1)
- Linux操作系统 (1)
- (BI)商业智能 (1)
- IOS (1)
- Windows Phone (2)
- C# API (1)
- JQuery系列 (1)
- TFS (1)
- C# (2)
- ExtJs (1)
- .NET (1)
- Nginx (1)
- WCF学习笔记 (1)
- Computer Graphic (1)
- IT产品 (1)
- 工具分享 (1)
- MySelf (1)
- C#专栏 (1)
- 管理 (1)
- 基于Oracle Logminer数据同步 (1)
- 日常 (1)
- 实用工具 (1)
- 网页设计 (1)
- avalon (1)
- flash (1)
- DDD (1)
- 01 技术Android (1)
- WCF (1)
- selenium (1)
最新评论
-
464410531:
三国杀。。。。。。。。。。。。。。。。。。。。。。。。。。。。 ...
实用的职场宝典:不提拔你,就因为你只想把工作做好
首先要说明一点,这个内存池使用时需要注意的,如果想用在长期分配出去的内存,请慎用.
因为假如一个区块被分配完了,只有在这个区块里已分配的内存被完全释放后,这个区块才能重用.
因为当初是设计为网络分包用的内存池.为了效率而采用这个策略的.
发代码之前先简单介绍下内存池的思路.
内存池分256个区块,编号为0~255
区块的结构为:
区块记录了3个信息一个指针
_left_mem是剩余的memory,初始化为区块内存总长
_alloc_org是指向区块有效内存的起始点.初始化为0(整个区块一开始都是可以有效分配出去的)
_need_to_rel是需要释放的内存.初始化为区块内存总长
内存块先简单介绍.后面再详细说实现细节
//区块,用于保存未分配内存(被分割出去)
struct _chunk{
int _left_mem; //此chunk剩余长度
int _alloc_org; //指向可用于分配内存快头的指针
int _need_to_rel;//需要释放多少内存
char _mem[1]; //此chunk持有的内存区
};
而分配出去的块用以下结构标识
struct _mem_piece{
int _mp_len; //内存块大小
char _chunk_index; //内存块所属区块的索引
char _mem[1]; //内存块的内存首地址
};
内存池的所有区块可以分为三个区域
无效区:这里的区块已经完全分配完毕,等待释放,释放完成后会到自由区
待分配区:这个区有且只有一个块,分配内存都会从这里抽取
自由区:
下图是内存池的状态:
内存池一开始会处于以下的状态
初始化的时候第一个区块会被初始化.继续分配就会耗尽绿色的待分配块,内存池会把它归入无效区,同时尝试从系统创建一个新的区块并列为待分配块
只有无效区的内存的块被完全释放后才会转到自由区.当然,如果自由区有区块的话,就不需要新建区块,而是直接指定自由区的第一个区块为待分配区块
然后我再来说明一下分配的策略._left_mem一开始就是该区块总内存大小这个不需要多说了.
malloc被调用时:
1.当_left_mem比要求分配的内存多的时候.把当前_alloc_org处分配出去,减少_left_mem和移动_alloc_org.
2.a.当_left_mem不足的时候,_left_mem(剩下的内存)将成为碎片,计算need_to_rel -= _left_mem,此区块将移动到无效区,并且内存池将获取一个新的区块(如果自由区有则直接获取,否则创建一个)
分配出去的时候都执行以下的代码:
则实际上需要的内存大小是sizeof(int) + sizeof(char) + memory size
而客户所得到的内存是从mp->_mem开始的.所以,free回来的内存只要向前移动5个字节就能获取到分配出去的_mem_piece结构了
_mem_piece *mp = (_mem_piece *)&p->_mem[p->_alloc_org];
//内存块真正的大小
mp->_mp_len = need_len;
//chunk标识
mp->_chunk_index = _S_cur_valid_index;
return mp->_mem;
b.计算need_to_rel -= _left_mem后发现need_to_rel==0则不是移动到无效区而是直接移动到自由区.
free被调用时:
_need_to_rel-=被释放的内存大小,发现_need_to_rel == 0则直接把此块移动到自由区
free调用的时候是这样获取到回来的内存大小的
_mem_piece *pmem = (_mem_piece *)((char *)p - _mem_piece::_mem_piece_struct_size);
_mem_piece记录了这块被分配的内存有多大.直接通过pmem->_mp_len获取,pmem->_chunk_index则记录了属于哪个区块的,这样便可以直接合并回该区块了.
shrink被调用时:
把所有处于自由区的区块释放,调用c标准库的free把内存还给系统,左右瘦身收敛的效果.
_need_to_rel仅仅是一个标记.在调用free的时候如果发现_need_to_rel==0了就直接把这个区块丢到自由区里面.因为最终分配完这个区块以后需要释放的值应该为 区块总内存 - 剩余碎片.所以_need_to_rel一开始就是区块总内存了.在刚刚绿色的待分配被完全耗尽以后,在转入无效区之前,会计算出碎片大小(就是_left_mem)这个时候执行need_to_rel -= _left_mem计算出真实的需释放值.计算完后,程序如果发现need_to_rel==0不会归入无效区而是直接转到自由区
最后总结下这个内存池的优缺点:
优点:
1.分配的时候仅仅移动了指针,内存不足时(即创建新块的时候)调用到c运行库的malloc.如果不算上malloc的话.内存池分配只需要执行少于10个指令.
所以分配速度非常快
2.释放的时候不需要合并这个步骤.很多内存分配器都是在合并上用了很多时间.这个内存池不需要任何合并的动作
3.可以分配任意大小的内存.当然,太大的时候会委托给malloc
缺点:
1.如果分配完一个区块后会造成少量碎片
2.无效区域内的内存只有等完全释放了,这个块才可以重用,所以不适合长期占有内存池的内存.
这个很大限度限制了这个内存池的实用性.
然后贴个测试:
#include "fish_mem_pool.h"
#include <boost/timer.hpp>
#include <iostream>
int main()
{
boost::timer t;
for (int i = 0; i < 1024 * 600; ++i)
char *p = (char *)fishlib::fish_mem_pool::malloc(1024);
std::cout << "used " << t.elapsed() << " seconds" << std::endl;
getchar();
return 0;
}
结果:
最后上代码:
配置内存池的头文件:
注意!内存池最大内存大小为256 * _new_chunk_len
这里为 256 * 4096000 = 1000MB
fish_mem_pool_config.h
/* @fish_mem_pool_config.h ----------------------------------------------
Copyright (c) TCC 2013
Project :
fish & Date : 2012/09/06
Files :
Brief : 根据枚举值,和宏定义改变fish_mem_pool的配置
Update :
Note :
-----------------------------------------------------------------*/
#ifndef _FISHLIB_FISH_MEM_POOL_CONFIG_H_
#define _FISHLIB_FISH_MEM_POOL_CONFIG_H_
#define _MULTI_THREAD_ //定义多线程环境
//这里是采用了boost做多线程同步,可以自行更改
//但是必须符合lock和unlock的接口
//多线程宏定义
#ifdef _MULTI_THREAD_
#include <boost/thread/mutex.hpp>
//#include <boost/signals2/mutex.hpp>
typedef boost::mutex _LOCK_CORE;
#endif //_MULTI_THREAD_
namespace fishlib{
enum _config_val{
_max_len = 4096, //内存池能分配的最大内存数,大于这个数的全都使用malloc
_new_chunk_len = 4096000 //新chunk的长度
//因为只有256个区块,所以内存池最多能分配_new_chunk_len * 256的内存
//请衡量_max_len / _new_chunk_len的值,这个值越大则一个chunk的利用率可能会下降
//_max_len / _new_chunk_len越小,则chunk的利用率越高
//尽量保持在1/2以下
};
}
#endif //_FISHLIB_FISH_MEM_POOL_CONFIG_H_
内存池的声明头文件:
fish_mem_pool.h
/* @fish_mem_pool.h ----------------------------------------------
Copyright (c) TCC 2013
Project :
fish & Date : 2012/09/06
Files :
Brief :
Update :
Note :
-----------------------------------------------------------------*/
#ifndef _FISHLIB_FISH_MEM_POOL_H_
#define _FISHLIB_FISH_MEM_POOL_H_
namespace fishlib{
class fish_mem_pool{
public:
/*
*大于_max_len的直接用malloc分配,分配失败返回NULL
*/
static void *malloc(int len);
/*
*由fishlib::fish_mem_pool::malloc分配的都要用这个函数释放
*/
static void free(void *p);
/*
*手动收缩,调用后内存池会把空闲块还给系统,返回释放了多少内存
*/
static int shrink();
};
}
#endif //_FISHLIB_FISH_MEM_POOL_H_
内存池实现文件:
fish_mem_pool.cpp
/* @fish_mem_pool.cpp ----------------------------------------------
Copyright (c) TCC 2013
Project :
fish & Date : 2012/09/06
Files :
Brief :
Update :
Note :
-----------------------------------------------------------------*/
#include "fish_mem_pool.h"
#ifndef _FISHLIB_FISH_MEM_POOL_CONFIG_H_
#include "fish_mem_pool_config.h"
#endif //_FISHLIB_FISH_MEM_POOL_CONFIG_H_
#include <stdlib.h>
#include <memory.h>
#include <assert.h>
//模板类,好处是如果没有用到则不会生成,甚至不会检测语法错误
template<typename T>
class _MEM_POOL_LOCK{
public:
//自动加锁
_MEM_POOL_LOCK(T &t_lock): _t_lock(t_lock){
_t_lock.lock();
}
//自动在跳出作用域时解锁
~_MEM_POOL_LOCK(){
_t_lock.unlock();
}
private:
T &_t_lock;
};
//多线程宏定义
#ifdef _MULTI_THREAD_
static _LOCK_CORE _S_lc;
#define FISH_LOCK _MEM_POOL_LOCK<_LOCK_CORE> mpl(_S_lc);
#ifdef _DEBUG
static _LOCK_CORE _S_dbg_lc;
#define FISH_DBG_LOCK _MEM_POOL_LOCK<_LOCK_CORE> mpl(_S_dbg_lc);
#endif //_DEBUG
#else
//在非多线程状态下,此宏定义不会做任何事情
#define FISH_LOCK
#ifdef _DEBUG
#define FISH_DBG_LOCK
#endif //_DEBUG
#endif //_MULTI_THREAD_
namespace fishlib{
enum default_val{
_max_chunk_cnt = 256 //最大区块数,默认值,只能是小于256的数字
};
//内存池全局变量
//记录内存池状态
struct _chunk;
static _chunk *_S_chunk_list[_max_chunk_cnt]; //区块表,记录所有区块
static unsigned char _S_cur_valid_index = 0; //当前指向的有效区块,有效区块有且只有一个
static unsigned char _S_invalid_index_s = 0; //第一个无效的区块
static unsigned char _S_invalid_cnt = 0; //无效区块总数
static int _S_total_chunk_cnt = 0; //总共的区块数
//////////////////////////////////////////////////////////////////////////
//内存池内部使用结构定义
#pragma pack(1)
//区块,用于保存未分配内存(被分割出去)
struct _chunk{
enum{
_chunk_struct_size = sizeof(int) + sizeof(int) + sizeof(int)
};
int _left_mem; //此chunk剩余长度
int _alloc_org; //指向可用于分配内存快头的指针
int _need_to_rel;//需要释放多少内存
char _mem[1]; //此chunk持有的内存区
inline static _chunk *new_chunk(){
if (_S_total_chunk_cnt < _max_chunk_cnt){
//如果总区块数小于最大限制则可以分配
_chunk *p = (_chunk *)::malloc(_chunk_struct_size + _new_chunk_len);
if (p == NULL)
//系统内存不足
return NULL;
//最终分配成功
++_S_total_chunk_cnt;
p->_alloc_org = 0;
p->_left_mem = _new_chunk_len;
p->_need_to_rel = _new_chunk_len;
return p;
}else{
return NULL;
}
}
inline static void delete_chunk(_chunk *p){
//一个chunk销毁,并且把内存交还给系统
--_S_total_chunk_cnt;
::free(p);
}
};
//内存块,用于记录已分配内存
struct _mem_piece{
enum{
_mem_piece_struct_size = sizeof(char) + sizeof(int)
};
int _mp_len; //内存块大小
char _chunk_index; //内存块所属区块的索引
char _mem[1]; //内存块的内存首地址
};
#pragma pack()
//////////////////////////////////////////////////////////////////////////
//用于内存池自动初始化的结构
struct _init_mem_pool{
_init_mem_pool(){
//内存池初始化代码
memset(_S_chunk_list, 0, _max_chunk_cnt * sizeof(_chunk *)); //清零
_S_chunk_list[0] = _chunk::new_chunk();
_S_cur_valid_index = 0;
_S_invalid_index_s = 0;
_S_invalid_cnt = 0;
}
~_init_mem_pool(){
}
};
//自动静态对象,在此调用初始化代码
static _init_mem_pool imp;
//助手函数
//从一个chunk中获取内存
static inline void *_get_mem(int need_len){
//取出当前有效chunk
_chunk *p = _S_chunk_list[_S_cur_valid_index];
if (p->_left_mem <= need_len){
//内存不足
//因为在剩余空间恰巧等于的时候情况比较复杂,故舍弃这种可能
return NULL;
}else{
_mem_piece *mp = (_mem_piece *)&p->_mem[p->_alloc_org];
//抽取内存
//剩余内存较少
//指向可用于分配内存快头的指针增加
p->_left_mem -= need_len;
p->_alloc_org += need_len;
//内存块真正的大小
mp->_mp_len = need_len;
//chunk标识
mp->_chunk_index = _S_cur_valid_index;
return mp->_mem;
}
}
//使释放无效区块,成为自由区块
static inline void _free_invalid_chunk(unsigned char index){
//把要成为自由chunk的区块变为初始状态
_S_chunk_list[index]->_alloc_org = 0;
_S_chunk_list[index]->_left_mem = _new_chunk_len;
_S_chunk_list[index]->_need_to_rel = _new_chunk_len;
//与第一个无效区块交换,再++_S_invalid_index_s使其挪出无效区域
_chunk *ptmp = _S_chunk_list[index];
_S_chunk_list[index] = _S_chunk_list[_S_invalid_index_s];
_S_chunk_list[_S_invalid_index_s] = ptmp;
++_S_invalid_index_s;
--_S_invalid_cnt;
}
//真正移动块
static inline void _in_next_chunk(){
//需要释放的内存 - 剩余内存,意义:剩余的内存不需要释放
unsigned char index = _S_cur_valid_index;
_chunk *p = _S_chunk_list[index];
int need_to_rel = p->_need_to_rel;
need_to_rel -= p->_left_mem;
p->_need_to_rel = need_to_rel;
//移动到下一个
++_S_cur_valid_index;
//扩充无效区域
++_S_invalid_cnt;
assert(p->_need_to_rel >= 0 && p->_need_to_rel <= _new_chunk_len);
if (p->_need_to_rel == 0){
//如果内存块其他分配出去的都被用完了
//那就让它直接成为自由chunk
_free_invalid_chunk(index);
}
}
//尝试移动区块
//失败返回false
static inline bool _next_chunk(){
unsigned char new_index = _S_cur_valid_index + 1;
if (new_index == _S_invalid_index_s){
//发现继续向前移动到达无效区域,则说明内存池已经彻底分配完了
return false;
}else{
//内存池尚有剩余位置
if (_S_chunk_list[new_index] == NULL){
//新位置尚未初始化,则向系统索取内存
_chunk *p = _chunk::new_chunk();
if (p == NULL){
//系统内存已经彻底耗尽了
return false;
}
else{
//初始化新位置
_S_chunk_list[new_index] = p;
//移动到新位置
_in_next_chunk();
return true;
}
}else{
//直接移动到新位置
_in_next_chunk();
return true;
}
}
}
//内存不足返回NULL
void *fish_mem_pool::malloc(int ilen){
assert(ilen > 0);
int real_need_len = ilen + _mem_piece::_mem_piece_struct_size;
if (real_need_len > _max_len){
//要求的内存太大
//委托给malloc
_mem_piece *p = (_mem_piece *)::malloc(real_need_len);
if (p == NULL)
return NULL;
p->_chunk_index = 0;
p->_mp_len = real_need_len;
return p->_mem;
}else{
//加锁
FISH_LOCK
void *p = _get_mem(real_need_len);
if (p == NULL){
//当前chunk的内存已经耗尽,尝试移动到下一个chunk
bool succeed = _next_chunk();
if (succeed){
return _get_mem(real_need_len);
}else{
return NULL;
}
}else{
return p;
}
}
}
void fish_mem_pool::free(void *p){
_mem_piece *pmem = (_mem_piece *)((char *)p - _mem_piece::_mem_piece_struct_size);
if (pmem->_mp_len <= _max_len){
//加锁
FISH_LOCK
unsigned char cindex = pmem->_chunk_index;
_S_chunk_list[cindex]->_need_to_rel -= pmem->_mp_len;
if (_S_chunk_list[cindex]->_need_to_rel == 0){
//发现需要释放的内存已经释放完,则让chunk变为自由chunk
_free_invalid_chunk(cindex);
}
}else{
//内存块太大,是委托给malloc的内存块
::free(pmem);
}
}
int fish_mem_pool::shrink(){
//加锁
FISH_LOCK
unsigned char cur_index = _S_cur_valid_index + 1;
unsigned char free_cnt = _max_chunk_cnt - (_S_invalid_cnt + 1);
int index = 0;
int end = free_cnt;
int cnt = 0;
//释放所有自由区块
for (; index < end; ++cur_index, ++index){
if (_S_chunk_list[cur_index] != NULL){
++cnt;
//必须为自由chunk
assert(_S_chunk_list[cur_index]->_need_to_rel == _new_chunk_len);
_chunk::delete_chunk(_S_chunk_list[cur_index]);
_S_chunk_list[cur_index] = NULL;
}
}
return (cnt * (_chunk::_chunk_struct_size + _new_chunk_len));
}
}
发表评论
-
Javascript:猜猜弹出的是啥?为啥? - 幸福框架
2013-06-28 13:33 430原帖地址:http://www.cnblogs.com/hap ... -
C#中WindowsForm常见控件的运用 -- - 李晓峰
2013-06-28 13:27 1747原帖地址:http://www.cnblogs.com/liy ... -
海量数据处理利器之Hash——在线邮件地址过滤 - MyDetail
2013-06-27 12:00 654原帖地址:http://www.cnblo ... -
ASP.NET MVC 4 for Visual Studio 2010 下载地址 - 张鸿伟
2013-06-27 11:48 754原帖地址:http://www.cnblogs.com/wei ... -
【ASP.NET Web API教程】6.2 ASP.NET Web API中的JSON和XML序列化 - r01cn
2013-06-26 11:00 919原帖地址:http://www.cnblogs.com/r01 ... -
[珠玑之椟]估算的应用与Little定律 - 五岳
2013-06-26 10:54 639原帖地址:http://www.cnblogs.com/wuy ... -
30行,金额转人民币大写的代码 - 史蒂芬.王
2013-06-26 10:42 1028原帖地址:http://www.cnblogs.com/ste ... -
从银行的钱荒看一个公司的团队建设 产品线过多最终导致最赚钱的项目面临破产 - James Li
2013-06-26 10:36 632原帖地址:http://www.cnblogs.com/Jam ... -
Windows 8 动手实验系列教程 实验6:设置和首选项 - zigzagPath
2013-06-25 13:39 535原帖地址:http://www.cnblogs.com/zig ... -
闲聊可穿戴设备 - shawn.xie
2013-06-25 13:33 616原帖地址:http://www.cnblo ... -
如何使用开源库,吐在VS2013发布之前,顺便介绍下VS2013的新特性"Bootstrap" - 量子计算机
2013-06-25 13:27 869原帖地址:http://www.cnblogs.com/DSh ... -
一步一步将自己的代码转换为观察者模式 - 文酱
2013-06-23 11:36 609原帖地址:http://www.cnblo ... -
iOS内存错误EXC_BAD_ACCESS的解决方法(message sent to deallocated instance) - VicStudio
2013-06-23 11:30 543原帖地址:http://www.cnblogs.com/vic ... -
记录asp.net在IE10下事件丢失排错经过 - Adming
2013-06-23 11:24 712原帖地址:http://www.cnblogs.com/wea ... -
记 FineUI 官方论坛所遭受的一次真实网络攻击!做一个像 ice 有道德的黑客! - 三生石上
2013-06-23 11:18 793原帖地址:http://www.cnblogs.com/san ... -
3、使用Oracle Logminer同步Demo
2013-06-19 10:33 571原帖地址:http://www.cnblogs.com/shi ... -
算法实践——数独的基本解法
2013-06-19 10:27 1450原帖地址:http://www.cnblogs.com/gre ... -
简单实现TCP下的大文件高效传输
2013-06-19 10:21 692原帖地址:http://www.cnblogs.com/sma ... -
avalon - 初步接触
2013-06-18 10:06 784原帖地址:http://www.cnblogs.com/aar ... -
Nginx学习笔记(一) Nginx架构
2013-06-18 09:59 529原帖地址:http://www.cnblogs.com/cod ...
相关推荐
5. **多线程和并发**:SGI IRIX操作系统支持多线程编程,库中可能包含线程管理和同步原语,如互斥锁、条件变量和信号量,以支持高效的并发执行。 6. **内存管理**:库中可能包含高级的内存分配和管理工具,帮助...
SGI映像总裁是一款高效实用的系统管理软件,它集成了多种功能,如系统备份、系统还原、拓展设置、分区克隆和磁盘克隆,旨在为用户提供一站式解决方案。该工具特别适用于支持GPT分区和UEFI引导的现代计算机系统,这...
SGI STL,全称为Stanford Graphics Group Standard Template Library,是由SGI公司开发并推广的一套C++标准模板库。这个库极大地丰富了C++的容器、迭代器、算法和函数对象,为C++程序员提供了高效且灵活的抽象数据...
标题 "sgi.rar_V2" 暗示了这是一个与SGI(Silicon Graphics Inc.)相关的软件组件,可能是一个驱动程序或系统级别的代码库。V2 表明这是该组件的第二个版本。描述中提到“Code extracted drivers block genhd for ...
SGI STL,全称为Silicon Graphics Incorporated Standard Template Library,是由SGI公司(现为MIPS Technologies Inc.)设计和实现的一个C++标准模板库。它为C++编程提供了高效的容器、迭代器、算法和函数对象,极...
内存池是一种内存分配策略,它的核心思想是预先分配一大块连续的内存空间,然后根据需要从中切分出小块内存给多个对象使用。这种方法避免了系统级的内存分配和释放操作,减少了内存碎片,提高了分配和回收内存的速度...
每个容器都有其特定的内存管理和访问性能特征,例如向量提供随机访问,而列表则支持高效的插入和删除操作。 2. **迭代器**:迭代器是SGI-STL的重要组成部分,它类似于指针,但提供了更多的操作,如前向移动、反向...
NUMAflex计算架构是SGI开发的一种非统一内存访问(NUMA)架构,优化了多处理器系统中数据的访问速度。在Altix 3000系列中,每个节点运行独立的Linux操作系统映像,并通过SGI NUMAlink系统互联光纤结构进行通信,传输...
STL(Standard Template Library,标准模板库)是C++编程中不可或缺的一部分,它提供了一组高效、可重用的数据结构和算法。这个压缩包“SGI-STL-.rar_STL_sgi stl”包含了SGI(Silicon Graphics, Inc.)版本的STL...
在内存管理领域,内存池是一种高效的内存分配机制,它预先从堆(heap)中分配出一大块内存,然后以池(pool)的形式管理这些内存。程序员可以直接从内存池中申请和释放内存,无需频繁与操作系统的内存管理器进行交互...
SGI-STL(Silicon Graphics, Inc. Standard Template Library)是C++编程语言中的一个经典实现,它提供了标准模板库的全面源代码。这个压缩包包含的资源是"The Annotated STL Sources V3.3",这是一个针对SGI-STL的...
信息安全网络隔离装置-SGI-NDS200用户操作手册.doc
文章中提到的SGI STL内存池管理方案,通过`node_alloc_impl::S_fill()`函数实现了内存块的动态分配和回收。这个函数会从内存池中取出指定数量和大小的内存块,如果内存池中没有可用的内存块,它会创建新的链表并将新...
3. **内存管理**:`sgi-memory.doc` 可能涵盖了STL中的内存分配器,如SGI的alloc,它是如何优化内存分配和管理的。 4. **源码解析**:`stl-source-sgi-alloc.doc` 专门讨论了SGI STL中的内存分配器源码,这对于深入...
5. **分配器(Allocator)**:分配器负责在内存中为容器分配和释放空间,STL提供了默认的全局分配器,同时也支持自定义分配器,以满足特定内存管理需求。 通过阅读SGI STL的源代码,我们可以了解到如何使用模板元...
1. **理解原版Allocator**:首先,你需要深入理解SGI-STL的Allocator是如何工作的,包括它的内部实现细节,如内存块的大小管理、内存池的概念以及如何减少内存碎片。 2. **需求分析**:确定你的项目对内存管理的...
SGI STL(斯坦福大学图形小组标准模板库)是C++编程中的一种经典实现,它提供了许多容器,如vector、list、map等,用于高效的数据存储和操作。vector是STL中最常用的一种动态数组,它允许在任何位置插入和删除元素,...
"多线程OpenGL渲染模型" 本文研究了基于OpenGL的动态多场景并行渲染,使用多线程技术实现了 OpenGL 动态多场景的并行渲染,并给出了虚拟烟花和碎片的实例。 一、OpenGL概述 OpenGL(Open Graphics Library)是一...
2. **行业标准支持**:Linux社区提供的应用程序和工具涵盖了业务、技术及系统管理等多个领域的问题解决,并且这些工具都是按照行业标准设计配置的,确保用户可以在SGI Altix系统上运行商业Linux应用、开源软件以及...