1. 程式人生 > >[轉]內存分配malloc, new , heapalloc

[轉]內存分配malloc, new , heapalloc

發現 handle read 很難 apc align 語言 c++編譯 可能

這裏比較的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. for( int 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.

[轉]內存分配malloc, new , heapalloc