-1

I'd like to implement a C++ function (using WIN32 API) to get current memory usage of my process.

I checked code from this post How to determine CPU and memory consumption from inside a process? and implemented the function.

bool GetMemoryUsage( size_t& usageInBytes )
{
    PROCESS_MEMORY_COUNTERS_EX pmc;
    if ( GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*) &pmc, sizeof(pmc)) )
    {
        usageInBytes = pmc.WorkingSetSize;
        return true;
    }
    else
    {
        return false;
    }
}

However, when I try to test it like that:

size_t initialMemoryUsage = 0;
GetMemoryUsage( initialMemoryUsage );

size_t use = 596;
void* memUsed = malloc( use );

size_t memoryUsage = 0;
GetMemoryUsage( memoryUsage );
assert( memoryUsage == initialMemoryUsage + 596 );

free( memUsed );

GetMemoryUsage( memoryUsage );
assert( memoryUsage == initialMemoryUsage );

It fails:

  • If GetMemoryUsage uses pmc.WorkingSetSize, memoryUsage is greater than initialMemoryUsage by 12288 and freeing memory does not make it decrease
  • If GetMemoryUsage uses pmc.PrivateUsage, memoryUsage and initialMemoryUsage are all equal, even after I allocated some memory

How can I implement GetMemoryUsage in an accurate and reliable way to have the test above pass?

Community
  • 1
  • 1
jpo38
  • 20,821
  • 10
  • 70
  • 151
  • 1
    Your expectations about how processes use memory are simply incorrect. The results you got are correct and show you what is actually happening. – David Schwartz Nov 10 '16 at 10:26
  • OK, so is there a way to know when some memory was allocated and how much? Or is that simply impossible? – jpo38 Nov 10 '16 at 10:28
  • 1
    It depends what you mean by "memory" and what you mean by "allocated". You are currently seeing when memory is allocated and how much. It's just not the kind of memory you think. (Physical? Virtual? Reserved? Resident? Or what?) And it's not "allocated" the way you think. (Reserved? Mapped? Containing useful data? Or what?) Without knowing precisely what you're trying to do, it's hard to help you do it. What question are you trying to answer? Be as specific as you can. – David Schwartz Nov 10 '16 at 10:30
  • [This](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366703(v=vs.85).aspx) might be what you want, but it's hard to tell. – David Schwartz Nov 10 '16 at 10:33
  • Actually, I want to check at runtime that a specific function call not introduce any memory leak. I want to check that any memory allocated by the function was released. So I need to know at some point how many memory was allocated by new/malloc and not released yet. – jpo38 Nov 10 '16 at 11:47

1 Answers1

0

Actually, I want to check at runtime that a specific function call not introduce any memory leak. I want to check that any memory allocated by the function was released. So I need to know at some point how many memory was allocated by new/malloc and not released yet.

Sorry, it just doesn't work that way.

 std::string foo()
 {
     return "hello";
 }

When this function returns, there may be a new std::string that didn't exist before. That doesn't indicate any leak.

You have expectations about how software works that just isn't how software works.

I think you would find it more fruitful to look at how programmers typically debug memory leaks. A very common mistake people make when asking for help solving a problem is that they come up with a way they think the problem should be solved and ask for help getting that way to work. That's what you're doing.

Instead, describe your actual problem in as much detail as possible and ask experts to suggest how they think you should solve it. They're more likely to suggest ways that will work.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • All right. Here is my problem description. I used VLD to detect and fix memory leaks in a critical function of our system. Now, to be sure no developer will introduce new leaks in the future, I want to add a new unit test to our system test suite, that will call the function and check that heap usage was not increased by the call. The test system does not integrates VLD and can't use Microsoft's heap CRT checker as it runs tests in Release mode. So I'd like to have a function that checks heap usage at some point. – jpo38 Nov 10 '16 at 19:06
  • You might want to ask a separate question to get more visibility. But I don't think that's easy to do without changes to your environment. You have chosen to specifically disable all the instrumentation and tools that would detect this. The release versions of the heap just don't keep this information precisely because it has a cost. Maybe somebody knows a way -- maybe an instrumented heap that you can link into a release build? – David Schwartz Nov 10 '16 at 19:10
  • By the way, a nice answer would explain me why `pmc.WorkingSetSize` is increased by 12288 after I did a `malloc( 596 )`... ;-) – jpo38 Nov 10 '16 at 19:10
  • Actually. Saying it's not possible would be an acceptable answer too ;-) – jpo38 Nov 10 '16 at 19:12
  • I don't know that it's not possible. It's hard to know exactly what happened. It may be that more pages of code faulted in. It may be that a large block was allocated from the OS and only a small piece of it was returned to you. It's very complicated. – David Schwartz Nov 10 '16 at 19:14
  • OK, got it, I thought it was more deterministic, that when you allocated n bytes, memory usage was increased by n bytes, not more. But it's probably not that simple, as you mentioned. – jpo38 Nov 10 '16 at 19:16
  • Only for a very special definition of "memory" and of "usage". When you call `malloc` and get back a pointer, you aren't using that memory yet -- you haven't even touched it. – David Schwartz Nov 10 '16 at 19:21