好的,因此,我编写了一些代码来检查运行时可用的内存量。下面是一个完整的(最小)cpp文件。
注意:该代码并不完美,也不是最佳实践,但是我希望您可以专注于内存管理,而不是代码。
它的作用(第一部分):

  • (1)在一个内存中分配尽可能多的内存
    堵塞。清除内存
  • (2)分配尽可能多的中型块
    (16MB)。清除该内存。

  • ->效果很好
    它的作用(第二部分):
  • (1)在一个块中分配尽可能多的内存。清除内存
  • (2)分配尽可能多的小块(16kb)。清除该内存。

  • ->这很奇怪!
    问题是:如果我重复一遍,我只能为以后运行的secons分配522kb --->吗?
    如果分配的块具有例如16MB的大小。
    您有什么想法,为什么会这样?
    // AvailableMemoryTest.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    
    #include <vector>
    #include <list>
    #include <limits.h>
    #include <iostream>
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    
        auto determineMaxAvailableMemoryBlock = []( void ) -> int
        {
            int nBytes = std::numeric_limits< int >::max();
    
            while ( true )
            {
                try
                {
                    std::vector< char >vec( nBytes );
                    break;
                }
                catch ( std::exception& ex )
                {
                    nBytes = static_cast< int >( nBytes * 0.99 );
                }
            }
            return nBytes;
        };
    
        auto determineMaxAvailableMemoryFragmented = []( int nBlockSize ) -> int
        {
    
            int nBytes = 0;
    
            std::list< std::vector< char > > listBlocks;
    
            while ( true )
            {
                try
                {
                    listBlocks.push_back( std::vector< char >( nBlockSize ) );
                    nBytes += nBlockSize;
                }
                catch ( std::exception& ex )
                {
                    break;
                }
            }
            return nBytes;
        };
    
    
        std::cout << "Test with large memory blocks (16MB):\n";
        for ( int k = 0; k < 5; k++ )
        {
            std::cout << "run #" << k << "   max  mem block          = " << determineMaxAvailableMemoryBlock() / 1024.0 / 1024.0 << "MB\n";
            std::cout << "run #" << k << "   frag mem blocks of 16MB = " << determineMaxAvailableMemoryFragmented( 16*1024*1024 ) / 1024.0 / 1024.0 << "MB\n";
            std::cout << "\n";
        } // for_k
    
    
        std::cout << "Test with small memory blocks (16k):\n";
        for ( int k = 0; k < 5; k++ )
        {
            std::cout << "run #" << k << "   max  mem block          = " << determineMaxAvailableMemoryBlock() / 1024.0 / 1024.0 << "MB\n";
            std::cout << "run #" << k << "   frag mem blocks of 16k  = " << determineMaxAvailableMemoryFragmented( 16*1024 ) / 1024.0 / 1024.0 << "MB\n";
            std::cout << "\n";
        } // for_k
    
        std::cin.get();
    
    
        return 0;
    }
    
    具有大内存块的输出(可以正常工作)
    Test with large memory blocks (16MB):
    run #0   max  mem block          = 1023.67MB     OK
    run #0   frag mem blocks of 16MB = 1952MB        OK
    
    run #1   max  mem block          = 1023.67MB     OK
    run #1   frag mem blocks of 16MB = 1952MB        OK
    
    run #2   max  mem block          = 1023.67MB     OK
    run #2   frag mem blocks of 16MB = 1952MB        OK
    
    run #3   max  mem block          = 1023.67MB     OK
    run #3   frag mem blocks of 16MB = 1952MB        OK
    
    run #4   max  mem block          = 1023.67MB     OK
    run #4   frag mem blocks of 16MB = 1952MB        OK
    
    带有小内存块的输出(从第二次运行开始,内存分配很奇怪)
    Test with small memory blocks (16k):
    run #0   max  mem block          = 1023.67MB     OK
    run #0   frag mem blocks of 16k  = 1991.06MB     OK
    
    run #1   max  mem block          = 0.493021MB    ???
    run #1   frag mem blocks of 16k  = 1991.34MB     OK
    
    run #2   max  mem block          = 0.493021MB    ???
    run #2   frag mem blocks of 16k  = 1991.33MB     OK
    
    run #3   max  mem block          = 0.493021MB    ???
    run #3   frag mem blocks of 16k  = 1991.33MB     OK
    
    run #4   max  mem block          = 0.493021MB    ???
    run #4   frag mem blocks of 16k  = 1991.33MB     OK
    
    更新:
    使用new和delete []代替STL的内部内存分配也可以实现这一点。
    更新:
    它适用于64位(我将两个功能均允许分配的内存限制为12GB)。真的很奇怪。这是该版本的RAM使用情况的图像:
    c&#43;&#43; - new和delete []比malloc和free更糟糕? (C&#43;&#43;/VS2012)-LMLPHP
    更新:
    它适用于malloc和free,但不适用于new和delete [](或如上所述的STL)

    最佳答案

    正如我在上面的评论中提到的,这很可能是堆fragmentation问题。堆将维护不同大小的块的列表,以满足不同的内存请求。对于较小的内存请求,将较大的内存块拆分为较小的块,以避免浪费块大小和请求大小之间的差异,从而减少了较大块的数量。因此,当请求更大的块时,堆可能没有足够的大块来满足请求。

    碎片是堆实现的主要问题,因为它有效地减少了可用内存。但是,某些堆实现能够将较小的块合并为较大的块,并且即使在多个较小的请求之后,也能够更好地满足较大的请求。

    我使用glibc的malloc(ptmalloc)运行了上面的代码,并对其进行了少许修改,结果如下:

    Test with large memory blocks (16MB):
    run #0   max  mem block          = 2048MB
    run #0   frag mem blocks of 16MB = 2032MB
    
    run #1   max  mem block          = 2048MB
    run #1   frag mem blocks of 16MB = 2032MB
    
    run #2   max  mem block          = 2048MB
    run #2   frag mem blocks of 16MB = 2032MB
    
    run #3   max  mem block          = 2048MB
    run #3   frag mem blocks of 16MB = 2032MB
    
    run #4   max  mem block          = 2048MB
    run #4   frag mem blocks of 16MB = 2032MB
    
    Test with small memory blocks (16k):
    run #0   max  mem block          = 2048MB
    run #0   frag mem blocks of 16k  = 2047.98MB
    
    run #1   max  mem block          = 2048MB
    run #1   frag mem blocks of 16k  = 2047.98MB
    
    run #2   max  mem block          = 2048MB
    run #2   frag mem blocks of 16k  = 2047.98MB
    
    run #3   max  mem block          = 2048MB
    run #3   frag mem blocks of 16k  = 2047.98MB
    
    run #4   max  mem block          = 2048MB
    run #4   frag mem blocks of 16k  = 2047.98MB
    

    因此,对于这种特定情况,ptmalloc似乎至少可以很好地处理碎片。

    10-08 05:51