[转]内存分配malloc, new , heapalloc

这里比较的VC++编译的C++代码中的性能

我用的是VC6.0测试的

就不介绍这几个的用法了

我写了一段简单的测试代码

测试结果是:

malloc:390
new:391
VirtualAlloc:454
HeapAlloc:47

很明显的是HeapAlloc分配速度最快,malloc次之,new和malloc差不多,VirtualAlloc最慢了(以前小强跟我说这个最快)

我有跟踪了一下

new调用了这段代码

  1. void * __cdecl _nh_malloc (
  2. size_t nSize,
  3. int nhFlag
  4. )
  5. {
  6. return _nh_malloc_dbg(nSize, nhFlag, _NORMAL_BLOCK, NULL, 0);
  7. }

malloc函数是这样的:

  1. _CRTIMP void * __cdecl malloc (
  2. size_t nSize
  3. )
  4. {
  5. return _nh_malloc_dbg(nSize, _newmode, _NORMAL_BLOCK, NULL, 0);
  6. }

很明显,new和malloc最终调用相同的_nh_malloc_dbg,只是new多了一次函数调用

再继续跟下去,发现最终调用的是return HeapAlloc(_crtheap, 0, size);

基本上真相大白了

VirtualAlloc跟踪不进去,如果说分配的是虚拟内存的话,有可能会慢吧。

回头再认真看看《Windows核心编程》这本书!

欢迎指正!欢迎交流!

测试代码如下:

  1. /******************************************************************
  2. *
  3. * Copyright (c) 2008, xxxx
  4. * All rights reserved.
  5. *
  6. * 文件名称:main.cpp
  7. * 摘    要: 测试申请内存的速度
  8. *
  9. * 当前版本:1.0
  10. * 作     者:吴会然
  11. * 完成日期:2008-11-30
  12. *
  13. * 取代版本:
  14. * 原   作者:
  15. * 完成日期:
  16. *
  17. ******************************************************************/
  18. #include <iostream>
  19. #include <windows.h>
  20. using namespace std;
  21. int main( int argc, char *argv[] )
  22. {
  23. int i = 0;
  24. DWORD dw1 = 0, dw2 = 0, dw3 = 0, dw4 = 0;
  25. DWORD dwStart = 0;
  26. DWORD dwEnd = 0;
  27. forint j = 0; j < 10; j++ )
  28. {
  29. dwStart = ::GetTickCount();
  30. for( i = 0; i < 20000; i++ )
  31. {
  32. char *pDest1 = (char *)malloc(4096);
  33. free( pDest1 );
  34. }
  35. dwEnd = ::GetTickCount();
  36. cout << "malloc 10000次4096大小的内存块,耗时" << dwEnd - dwStart << endl;
  37. dw1 += dwEnd - dwStart;
  38. dwStart = ::GetTickCount();
  39. for( i = 0; i < 20000; i++ )
  40. {
  41. char *pDest2 = new char[4096];
  42. delete pDest2;
  43. }
  44. dwEnd = ::GetTickCount();
  45. cout << "new 10000次4096大小的内存块,耗时" << dwEnd - dwStart << endl;
  46. dw2 += dwEnd - dwStart;
  47. dwStart = ::GetTickCount();
  48. for( i = 0; i < 20000; i++ )
  49. {
  50. void* pMem = ::VirtualAlloc(NULL, 4096,   MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
  51. ::VirtualFree(pMem, 0, MEM_RELEASE);
  52. }
  53. dwEnd = ::GetTickCount();
  54. cout << "VirtualAlloc 10000次4096大小的内存块,耗时" << dwEnd - dwStart << endl;
  55. dw3 += dwEnd - dwStart;
  56. HANDLE hHeap = ::HeapCreate(HEAP_NO_SERIALIZE, 0, 0);
  57. dwStart = ::GetTickCount();
  58. for( i = 0; i < 20000; i++ )
  59. {
  60. void* pMem2 = ::HeapAlloc(hHeap, HEAP_NO_SERIALIZE, 4096 );
  61. ::HeapFree(hHeap, HEAP_NO_SERIALIZE, pMem2);
  62. }
  63. dwEnd = ::GetTickCount();
  64. cout << "HeapAlloc 10000次4096大小的内存块,耗时" << dwEnd - dwStart << endl;
  65. dw4 += dwEnd - dwStart;
  66. }
  67. cout << "malloc:" << dw1 << endl;
  68. cout << "new:" << dw2 << endl;
  69. cout << "VirtualAlloc:" << dw3 << endl;
  70. cout << "HeapAlloc:" << dw4

====================================

转】李玮剑 评论
1 把分配的内存空间改为4M甚至更高(循环次数减少)试试,结果截然不同。处理M级的大文件时,用VirtualAlloc效率高

2 博主的测试需要考究,系统在创建线程时就已经预先在线程的堆栈段中提交了两个页面。 按照我的观点new和malloc只要消耗的内存没有超过页面大小就不会实际的进行存储器的保留与提交。二者的操作不在一个层面上。

3 在分配大于一个页面数据的时候 virtualAlloc才有意义

4 virtualAlloc是操作系统提供的最根本的内存分配接口。HeapAlloc预先使用virtualAlloc申请了大块的内存,并根据优化算法组织了用于内存管理的数据结构,主要是对小内存分配的优化 new和malloc是语言层面接口,由于HeapAlloc已经有了优化,所以vc中的malloc并没有使用更多的优化算法,直接转入 HeapAlloc。

内存管理有三种方式:

https://blog.csdn.net/zj510/article/details/39400087

1. 虚拟内存,VirtualAlloc之类的函数

2. 堆,Heapxxx函数,malloc,new等

3. 内存映射文件,Memory Mapped File

很多人都会困惑,但是看下面的图片就会比较明白了。这个图片从MSDN上拷来。

堆和虚拟内存,从上面的图片就可以看出,其实所谓的堆,也就是在虚拟内存上抽象出来的。如果直接用Virtualxxx系列函数,是有一些限制的,比如每次只能分配页大小倍数的内存,内存地址也必须对齐什么的。新手很难用。正因为如此,才出现了堆。实际上堆Heap内部就是使用Virtual系列函数的。基本思想就是:先用VirtualAlloc分配一个比较大的内存,然后用户每次申请堆内存的时候,从分配出来的虚拟内存块上指定一块给用户。比如第一次分配堆内存从A地址开始的100个字节,第二次分配的时候就是A+100开始。

Memory Mapped File就不太一样了,从上面的图可以看出MMF并没有调用Virtual系列函数。它直接调用内核层了。

对于malloc和new,这2个并不是操作系统API,它们是语言提供的函数。在不同的系统上面有不同的实现方法,在Windows上面,new调用malloc,malloc调用堆函数(heapxxx),堆函数调用Virtual系列函数。在Linux上面就调用相应的linux API.

原文地址:https://www.cnblogs.com/freebird92/p/9363307.html

时间: 2024-08-11 01:35:18

[转]内存分配malloc, new , heapalloc的相关文章

Win内存分配函数(GlobalAlloc/HeapAlloc/LocalAlloc/VirtualAlloc)

内存分配函数/内存管理API 参考: Windows MSDN http://msdn.microsoft.com/en-us/library/aa908768.aspx 附助资料: http://blog.csdn.net/susubuhui/article/details/7315094 http://wenku.baidu.com/link?url=yxgCWePPV1kFaIUciEspYgm34wNAnMLDoduBlfsEEo-mW0JFRVEOkixomUjPatqw_jOXZcq

Linux-(C/C++)动态内存分配malloc以及相关学习

1.C/C++内存分类(引用C++ Primer )(对象在C语言中可以理解为变量) 1.1.静态内存:静态内存用来保存局部static对象.类static数据成员.以及定义在任何函数之外的变量 1.2.栈内存:栈内存用来保存定义在函数内非static对象.(当然包含函数参数开辟的内存) 1.3.动态内存:每个程序还有一个内存池,这部分内存被称作自由空间(free store)或者堆(heap).程序用堆来存储动态分配的内存(dynamically allocate)的对象,也就是,那些在程序运

c语言中的内存分配malloc、alloca、calloc、malloc、free、realloc、sbr

C语言跟内存分配方式 (1) 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. (2) 在栈上创建.在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放.栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限. (3)从堆上分配,亦称动态内存分配.程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存.动态内存的

关于c语言内存分配,malloc,free,和段错误,内存泄露

1.   C语言的函数malloc和free (1) 函数malloc和free在头文件<stdlib.h>中的原型及参数        void * malloc(size_t size) 动态配置内存,大小有size决定,返回值成功时为任意类型指针,失败时为NULL. void  free(void *ptr) 释放动态申请的内存空间,调用free()后ptr所指向的内存空间被收回,如果ptr指向未知地方或者指向的空间已被收回,则会发生不可预知的错误,如果ptr为NULL,free不会有任

c语言内存分配-malloc

malloc 原型:(原来返回类型是char) 1 extern void *malloc(unsigned int num_bytes); 头文件: 1 #include <stdlib.h> 2 #include <malloc.h> 函数声明: void *malloc(size_t size); 返回值: 分配成功:返回被分配内存的指针 失败:返回NULL 不再使用时,可用free()函数释放内存 使用: 1 int *p,*s; 2 p=(int*)malloc(size

C语言中的动态内存分配,malloc/free

malloc函数 原型 extern void *malloc(unsigned int num_bytes); 头文件 #include <stdlib.h> 功能 分配长度为num_bytes字节的内存块 返回值 如果分配成功则返回指向被分配内存的指针(此存储区中的初始值不确定),否则返回空指针NULL.当内存不再使用时,应使用free()函数将内存块释放.函数返回的指针一定要适当对齐,使其可以用于任何数据对象. 说明 关于该函数的原型,在以前malloc返回的是char型指针,新的ANS

线性表的动态内存分配顺序存储结构

1.线性表是最简单的一种数据结构,很容易实现其中单个元素的存取操作,但是对于插入和删除操作需要大量的移动.比较适用于相对稳定的线性表. 2.数据元素 struct SqList { ElemType * elem ; //存储空间基址 int length ; //当前长度 int listsize ; //当前分配的存储容量 }; 3.创建一个空的线性表 void InitList(SqList &L) { //构造一个空的顺序线性表L L.elem = (ElemType*)malloc(L

C++解析(25):关于动态内存分配、虚函数和继承中强制类型转换的疑问

0.目录 1.动态内存分配 1.1 new和malloc的区别 1.2 delete和free的区别 2.虚函数 2.1 构造函数与析构函数是否可以成为虚函数? 2.2 构造函数与析构函数是否可以发生多态? 3.继承中的强制类型转换 4.小结 1.动态内存分配 1.1 new和malloc的区别 new关键字与malloc函数的区别: new关键字是C++的一部分 malloc是由C库提供的函数 new以具体类型为单位进行内存分配 malloc以字节为单位进行内存分配 new在申请内存空间时可进

String类型_static成员_动态内存分配_拷贝构造函数_const关键字_友元函数与友元类

1:String类型 1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 //初始化方法 6 string s1 = "hello";//默认构造方法 7 string s2(s1);//将s2初始化为s1的一个副本 8 string s3("value");//将s3初始化为字符串的副本 9 string s4(10,'x');//将字符串初始化为字符x的10个副本 10 co