Search code examples
c++boostmemory-poolboost-pool

boost::pool real memory allocations


I'm trying to use the boost::pool memory pool from #include "boost/pool/pool.hpp".
I want to check how much memory is allocated with boost::pool so I run the command system("ps aux | grep myProgramExe | grep -v grep | awk '{print $5}'"); which gives me the (from the ps man page) VSZ - virtual memory size of the process in KiB (1024-byte units). Device mappings are currently excluded; this is subject to change. (alias vsize).

I'm getting something strange:

  1. Code (code is indented 4 spaces, plus another 4 because it's embedded in a list)

    int main()
    {
        {
            boost::pool<> pool(4, 1);
            system("ps aux | grep boostHash | grep -v grep  | awk '{print \"1. \" $5}'");
            void *a = pool.malloc();
            pool.free(a);
            system("ps aux | grep boostHash | grep -v grep  | awk '{print \"2. \" $5}'");
        }
        system("ps aux | grep boostHash | grep -v grep  | awk '{print \"3. \" $5}'");
    }
    

The output is:

1. 18908
2. 19040
3. 19040

Which is strange, because:
a. I wanted to allocate only 4 bytes (the next allocation should be only 1 instance).
b. The memory isn't being free'd when the block is over and pool is dead.

  1. Now I want to allocate instance of size 128, and I want to allocate 1024 like this in the next allocation:

    int main()
    {
        {
            boost::pool<> pool(128, 1024);
            system("ps aux | grep boostHash | grep -v grep  | awk '{print \"4. \" $5}'");
            void *a = pool.malloc();
            pool.free(a);
            system("ps aux | grep boostHash | grep -v grep  | awk '{print \"5. \" $5}'");
        }
        system("ps aux | grep boostHash | grep -v grep  | awk '{print \"6. \" $5}'");
    }
    

Output:

4. 18908
5. 19040
6. 18908

Which is fine, because:

a. I wanted to allocate 128 * 1024 = 131072 bytes, and got 19040 - 18908 = 132KB = 135168 bytes. 135168 - 131072 = 4096 bytes (that's just the pool over head, I think).
b. When the block ended, the memory was free'd.

  1. destructor

    int main() {
        {
            boost::pool<> *pool = new boost::pool<>(128, 1024);
            system("ps aux | grep boostHash | grep -v grep  | awk '{print \"7. \" $5}'");
            void *a = pool->malloc();
            pool->free(a);
            delete pool;
            system("ps aux | grep boostHash | grep -v grep  | awk '{print \"8. \" $5}'");
        }
        system("ps aux | grep boostHash | grep -v grep  | awk '{print \"9. \" $5}'");
    }
    

Output:

7. 19040
8. 19040
9. 19040

This is strange,
a. For some reason, the size is already allocated (before I called pool.malloc().
b. The size isn't being free'd in delete.

Is this explainable?
Do I need to use another tool instead of ps to see the memory used by the program?


Solution

  • Is this explainable?

    Yes.

    Do I need to use another tool instead of ps to see the memory used by the program?

    You are seeing the memory used by the program.

    What you didn't take into account: memory allocation routines are heavily optimized. Libraries (like libc) will use various strategies to make allocation/reallocation faster, for various scenarios. Here are some common memory management strategies:

    • request memory preemptively, from the operating system; this allows the application to perform subsequent internal allocations of the same type, without the cost of requesting more memory from the OS;

    • caching released memory; this allows an applications to reuse memory (received from the OS) for subsequent allocations (and again, avoid the overhead of talking with the OS about it)