我正在阅读和实验这本书的指针,
http://shop.oreilly.com/product/0636920028000.do
在本书的第6章中,>避免使用malloc/free开销标题作者在进行大量结构内存分配/交易时,建议如何避免Malloc/Free开销。
以下是他写下功能的方式
#define LIST_SIZE 10
Person *list[LIST_SIZE];
void initializeList()
{
int i=0;
for(i=0; i<LIST_SIZE; i++)
{
list[i] = NULL;
}
}
Person *getPerson()
{
int i=0;
for(i=0; i<LIST_SIZE; i++)
{
if(list[i] != NULL)
{
Person *ptr = list[i];
list[i] = NULL;
return ptr;
}
}
Person *person = (Person*)malloc(sizeof(Person));
return person;
}
void deallocatePerson(Person *person)
{
free(person->firstName);
free(person->lastName);
free(person->title);
}
Person *returnPerson(Person *person)
{
int i=0;
for(i=0; i<LIST_SIZE; i++)
{
if(list[i] == NULL)
{
list[i] = person;
return person;
}
}
deallocatePerson(person);
free(person);
return NULL;
}
我从他的代码中了解的是,他创建了一个内存池阵列,指向 struct Person type,然后用null初始化每个数组元素。
接下来,我们将使用 getPerson 函数从池中获得内存。此功能,对!= null 检查,我认为每次都会失败。因此,同样会一样,因为做malloc和内存不会随时从池中分配。
- 我的理解正确吗?
- 这是处理开销的方式吗?
- 正确的方法应该是什么?任何来源/链接都将不胜感激。
接下来,我们将使用GetPerson函数从池中获得内存。此功能,对
!=NULL
进行检查,我认为每次都会失败。
只要您继续反复致电getPerson
,则该检查将每次失败。但是,如果您将getPerson
和returnPerson
的混合物混合在一起,则某些NULL
检查将成功,因为returnPerson
将非NULL
值放入数组中。
此观察是理解方法的关键:该数组是已分配给malloc
的struct Person
块的小临时存储,但不再使用。如果有可用的话,您的代码不是再次致电malloc
,而是从此特殊列表中获取可用块。
在您进行数千个分配的情况下,但在任何给定时间中都不保留比LIST_SIZE
对象多的情况,malloc
调用的数量仅限于LIST_SIZE
。
这是处理开销的方式吗?
这是使用LookAside列表的一种变体,这是一种非常重要的优化技术,以至于Microsoft创建了用于在驱动程序代码中使用的API。一种更简单的方法将使用Person *list[LIST_SIZE]
用作已发布的块的堆栈,即最后发布块的索引,没有循环。
另一种方法是设置此类块的链接列表,重用块本身的内存以存储next
指针。不过,此技术对于入门嘘声可能太复杂了。
首先,您的作者指的是在这里指的是什么?对于动态内存分配,我们调用malloc
分配内存和free
以释放内存。同样在此过程中,操作系统也需要从堆中搜索可用的内存并分配相同的内存。为了避免这种开销,他只是建议一开始,当您的应用程序加载以及您知道可能的动态内存分配到struct
的频率,您可以提前保留一个存储器库,这将减少内存的分配和交易分配高架高度。在一定程度上,如果您的服务器已经运行了很多应用程序,并且处理器很忙,则可以采用这种方法。但是也有缺点。在这种情况下,您已经提前从堆中保留了一个内存池。如果未正确使用,它将导致内存管理差。
我认为示例的重点可能是 Person
对象将指针固定在其他内存中。我们可以从deallocatePerson
函数中看到,结构内有3个指针:
void deallocatePerson(Person *person)
{
free(person->firstName);
free(person->lastName);
free(person->title);
}
这意味着要构建一个完整的Person
,您需要几个呼叫malloc
(结构本身为1,字符串为3(。
因此,通过保存完整的结构(包括其字符串(,一个getPerson
呼叫替换四个呼叫malloc
。这可能会节省某些执行时间。
否则,如果malloc
/ free
内部保存了类似的数组或链接的列表,我不会感到惊讶。如果您只有free
'D正确大小的内存块,则可以将malloc
的新调用定位为非常 fast。
Person
是一个简单的结构(。