title: How to measure fragmentation in OSX and WIN
body: <p>Our clients experience <a href="https://en.wikipedia.org/wiki/Out_of_memory" rel="nofollow noreferrer">OOM</a> in some specific scenarios and we can't pinpoint any memory leaks so we would like to understand if it's a memory fragmentation issue.</p>
  <p>There are a lot of different memory metrics in both OSX and WIN (resident, dirty, working set, reserved, committed, ...) and we can't figure out which metrics we can use to measure fragmentation.</p>
  <p><code>vmmap</code> command in OSX presents a fragmentation column and it seems to be measured as follows :</p>
  <pre><code>(DIRTY+SWAP FRAG SIZE) = DIRTY SIZE - BYTES ALLOCATED
  
  FRAG = (DIRTY+SWAP FRAG SIZE) / DIRTY SIZE x 100.0
  </code></pre>
  <p><a href="https://i.stack.imgur.com/mDfwn.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/mDfwn.png" alt="" /></a></p>
  <p>The question is how we can retrieve <code>DIRTY SIZE</code> and <code>BYTES ALLOCATED</code> ?</p>
  <p>There is <a href="https://opensource.apple.com/source/Libc/Libc-594.1.4/gen/malloc.c" rel="nofollow noreferrer">mstats</a> which gives the amount of memory allocated and used via <code>malloc</code> but the reported values doesn't match anything we see in vmmap.</p>
  <p><a href="https://i.stack.imgur.com/2M6vU.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/2M6vU.png" alt="" /></a></p>
  <p>WIN is also a totally different story. We had a look at the following values but we don't know if they can be used to measure fragmentation:</p>
  <pre><code>static void vminfo (unsigned long *free, unsigned long *reserved, unsigned long *committed) {
      MEMORY_BASIC_INFORMATION memory_info;
      memory_info.BaseAddress = 0;
      *free = *reserved = *committed = 0;
      while (VirtualQuery (memory_info.BaseAddress, &amp;memory_info, sizeof (memory_info))) {
          switch (memory_info.State) {
          case MEM_FREE:
              *free += memory_info.RegionSize;
              break;
          case MEM_RESERVE:
              *reserved += memory_info.RegionSize;
              break;
          case MEM_COMMIT:
              *committed += memory_info.RegionSize;
              break;
          }
          memory_info.BaseAddress = (char *) memory_info.BaseAddress + memory_info.RegionSize;
      }
  }
  </code></pre>
  <p>We also had a look at <a href="https://docs.microsoft.com/en-us/windows/win32/api/psapi/nf-psapi-getprocessmemoryinfo" rel="nofollow noreferrer">GetProcessMemoryInfo</a> and same story, we don't know if and how  values from <a href="https://docs.microsoft.com/en-us/windows/win32/api/psapi/ns-psapi-process_memory_counters_ex" rel="nofollow noreferrer">PROCESS_MEMORY_COUNTERS_EX</a> can be used to measure fragmentation.</p>
  <p>TLDR : How can we measure fragmentation in OSX and WIN ?</p>