A StringIO()
object does not make a copy of a string passed to it. There is no need to, as strings are not mutable.
When reading data from a StringIO()
object in chunks, new string objects are created that are substrings from the original input string.
Memory consumption never goes down immediately when freeing objects. Memory allocation is only redistributed as needed by the OS, and many types of (small) objects can be interned by Python for efficiency and are never freed, only reused.