C++ allocates abnormally large amout memory for variables

后端 未结 9 737
名媛妹妹
名媛妹妹 2020-12-10 14:13

I recently got to know an integer takes 4 bytes from the memory.

First ran this code, and measured the memory usage:

int main()
{
   int *pointer;
         


        
相关标签:
9条回答
  • 2020-12-10 14:32

    You are allocating more than just an int, you are also allocating a heap block which has overhead (which varies by platform). Something needs to keep track of the heap information. If you instead allocated an array of ints, you'd see memory usage more in line with your expectations.

    0 讨论(0)
  • 2020-12-10 14:34

    Each time you allocate an int:

    • The memory allocator must give you a 16-byte aligned block of space, because, in general, memory allocation must provide suitable alignment so that the memory can be used for any purpose. Because of this, each allocation typically returns at least 16 bytes, even if less was requested. (The alignment requires may vary from system to to system. And it is conceivable that small allocations could be optimized to use less space. However, experienced programmers know to avoid making many small allocations.)
    • The memory allocator must use some memory to remember how much space was allocated, so that it knows how much there is when free is called. (This might be optimized by combining knowledge of the space used with the delete operator. However, the general memory allocation routines are typically separate from the compiler’s new and delete code.)
    • The memory allocator must use some memory for data structures to organize information about blocks of memory that are allocated and freed. Perhaps these data structures require O(n•log n) space, so that overhead grows when there are many small allocations.

    Another possible effect is that, as memory use grows, the allocator requests and initializes larger chunks from the system. Perhaps the first time you use the initial pool of memory, the allocator requests 16 more pages. The next time, it requests 32. The next time, 64. We do not know how much of the memory that the memory allocator has requested from the system has actually been used to satisfy your requests for int objects.

    Do not dynamically allocate many small objects. Use an array instead.

    0 讨论(0)
  • 2020-12-10 14:37

    I think it depends on how the compiler creates the output program.

    The memory usage of a program includes all the sections of the program (like .text, which contains the assembly directives of the program), so it takes some memory in space, when it's loaded.

    And for more variables, the memory isn't really contiguous when you allocate some memory (memory-alignment), so it could take more memory than you think it takes.

    0 讨论(0)
  • 2020-12-10 14:39

    In addition to the alignment and overhead issues mentioned in the other questions, this may be due to the way the C++ runtime requests process memory allocations from the OS.

    When the process's data section fills up, the runtime has to get more memory allocated to the process. It might not do this in equal-sized chunks. A possible strategy is that each time it requests memory, it increases the amount that it request (maybe doubling the heap size each time). This strategy keeps the memory allocation small for programs that don't use much memory, but reduces the number of times that a large application has to request new allocations.

    Try running your program under strace and look for calls to brk, and note how large the request is each time.

    0 讨论(0)
  • 2020-12-10 14:43

    You are allocating multiple dynamic variables. Each variable contain 4 bytes of data, but a memory manager usually stores some additional information about allocated blocks, and each block should be aligned, that creates additional overhead.

    Try pointer = new int[262144]; and see the difference.

    0 讨论(0)
  • 2020-12-10 14:45

    Memory for individually allocated dynamic objects is not required to be contiguous. In fact, due to the alignment requirements for new char[N] (namely to be aligned at alignof(std::maxalign_t), which is usually 16), the standard memory allocator might just never bother to return anything but 16-byte aligned memory. So each int allocation actually consumes (at least) 16 bytes. (And further memory may be required by the allocator for internal bookkeeping.)

    The moral is of course that you should be using std::vector<int>(1000000) to get a sensible handle on one million dynamic integers.

    0 讨论(0)
提交回复
热议问题