When you ask for memory, MM(FastMM) asks the OS for a large chunks and then it splits them and gives you a piece (based on the size you need). When the object is destroyed (free), the memory is returned to the MM. Now, based on the returned size, the MM may either choose to recycle the object location (if its small) or return the memory to the OS (a real-free-op). What you're doing in MultiplyStr is not just wasteful but extremely harmful ! For each iteration you're reallocating memory. Allocating a new block and copying the old block to the new one. It's very important to know that small block are implemented as a segregated list. i.e if you ask for a 32 bytes, MM on reality allocates an entire table i.e 32x32=1024 bytes and yields first block. In your example you said you used 1GB ! this is extremely bad because you're not economizing resources and you'll quickly run out of memory i.e another thread that asks for a large chunk. It's indeed a good practice to pre-allocate memory : function MultiplyStr(aStr: string; aMultiplier: integer): string; var i: Integer; begin SetLength(Result, length(aStr) * aMultiplier); for i := 1 to aMultiplier do Result := Result + aStr; end;  Please run the above and notice the memory and performance !!! Also a small remark ! aStr should be const !!!
    • Thanks
    1