内存管理_001
基础知识
0 堆(heap)与栈(stack)
在数据结构和操作系统中代表不同的东西
0.1 数据结构中
数据结构中的堆就是优先队列, 栈就是一种先进后出的线性表.
0.2 操作系统中
操作系统中的堆和栈都是指内存空间, 区别在于分配内存的方式不同.
0.2.1 堆
堆为按需申请、动态分配. 也就是说堆中内存由程序员手动分配, 在程序结束时由操作系统释放.
new或者molloc出来的对象是放在堆中, 需要有相应的delete或free, 不然可能会造成内存泄漏.
0.2.2 栈
程序运行时自动拥有的一小块内存,大小在编译期时由编译器参数决定,用于局部变量的存放或者函数调用(比如递归)栈的保存.
比如在函数中定义一个局部变量, 函数执行完后, 这个变量就自动释放了.
malloc/new
//栈
cat a();
//堆
cat* a = new cat();
// C 中用 malloc() 函数申请
char* p1 = (char *)malloc(10);
cout<<(int*)p1<<endl; //输出:00000000003BA0C0
// 用 free() 函数释放
free(p1);
// C++ 中用 new 运算符申请
char* p2 = new char[10];
cout << (int*)p2 << endl; //输出:00000000003BA0C0
// 用 delete 运算符释放
delete[] p2;
allocator
(待续)
内存池 [转载]
作者:linux技术栈
链接:https://zhuanlan.zhihu.com/p/375537583
1. 什么是内存池
1.1 池化技术
- 池是在计算技术中经常使用的一种设计模式,其内涵在于:将程序中需要经常使用的核心资源先申请出来,放到一个池内,有程序自管理,这样可以提高资源的利用率,也可以保证本程序占有的资源数量,经常使用的池化技术包括内存池,线程池,和连接池等,其中尤以内存池和线程池使用最多。
1.2 内存池
-
内存池(Memory Pool)是一种动态内存分配与管理技术,通常情况下,程序员习惯直接使用new,delete,malloc,free等API申请和释放内存,这样导致的后果就是:当程序运行的时间很长的时候,由于所申请的内存块的大小不定,频繁使用时会造成大量的内存碎片从而降低程序和操作系统的性能。
-
内存池则是在真正使用内存之前,先申请分配一大块内存(内存池)留作备用。当程序员申请内存时,从池中取出一块动态分配,当程序员释放时,将释放的内存放回到池内,再次申请,就可以从池里取出来使用,并尽量与周边的空闲内存块合并。若内存池不够时,则自动扩大内存池,从操作系统中申请更大的内存池。
2. 为什么需要内存池
2.1 内存碎片问题
造成堆利用率很低的一个主要原因就是内存碎片化。如果有未使用的存储器,但是这块存储器不能用来满足分配的请求,这时候就会产生内存碎片化问题。内存碎片化分为内部碎片和外部碎片。
-
内碎片
内部碎片是指一个已分配的块比有效载荷大时发生的。(假设以前分配了10个大小的字节,现在只用了5个字节,则剩下的5个字节就会内碎片)。内部碎片的大小就是已经分配的块的大小和他们的有效载荷之差的和。因此内部碎片取决于以前请求内存的模式和分配器实现(对齐的规则)的模式。 -
外碎片
假设系统依次分配了16byte、8byte、16byte、4byte,还剩余8byte未分配。这时要分配一个24byte的空间,操作系统回收了一个上面的两个16byte,总的剩余空间有40byte,但是却不能分配出一个连续24byte的空间,这就是外碎片问题。