winapimemory-managementcomctl32

Free Heap of Edit Control after setting the text to a large amount of data?


I was looking at my process in Task manager after pulling in a large amount of data that went to a CEditView then setting back to small amount. I noticed the commit size stayed large. Then I used VMMMap and see it as well, so I did "Memory Usage" in VS2017 Diagnostic Tools. I see it's coming from ultimately the ::SetWindowText() call. So that obviously allocates a large buffer on the heap, but then when I set it back to a small amount, that allocate stays large. The question is, is there a way I can have the Edit Control free up the memory it doesn't need for smaller amounts of text to reduce that committed memory? Say, I can free it up before setting the new text and it would allocate as needed?

Thanks!!


Solution

  •   // From within CEditView
      
      // based on an answer RbMm using EM_GETHANDLE/EM_SETHANDLE and further
      // from https://stackoverflow.com/questions/5500237/how-to-use-em-sethandle-on-edit-control
     
      // reduce size to 64K if larger than that and not needed
      #define EDITctrlLimitSize 65536  
     
      // check if we should reduce size of buffer
      HLOCAL horgmem = (HLOCAL) SendMessage(EM_GETHANDLE,0,0);
      SIZE_T sizeused=LocalSize(horgmem);
     
      int cbCh = sizeof(TCHAR) > 1 ? sizeof(TCHAR) : IsUsingComCtlV6() ? sizeof(WCHAR) : sizeof(char);
      if (sizeused > EDITctrlLimitSize && (string.GetLength()*cbCh) < EDITctrlLimitSize) {
        // EM_GETHANDLE says to not change the data, yet EM_SETHANDLE tells you to
        // get the handle then LocalFree it, so why not just LocalReAlloc it and set
        // again.
        HLOCAL hnewmem=(HLOCAL) LocalReAlloc(horgmem, EDITctrlLimitSize, LMEM_MOVEABLE);
        if (hnewmem) {
          // zero full buffer because seems like good thing to do
          LPVOID pnewmem=LocalLock(hnewmem);
          if (pnewmem) {
            memset(pnewmem, 0, EDITctrlLimitSize);
            LocalUnlock(hnewmem);
          }
    
          // viola - process memory reduced.
          SendMessage(EM_SETHANDLE, (WPARAM) hnewmem, 0);
        }
      }