Looking at debugserver's memory use a bit, I noticed that the SendPacket method which takes a std::string& argument, is often called with a std::string object that the caller calls c_str() on, so a temporary copy of the string is created. This patch removes those c_str() method calls.
We also have a common pattern where we have/create a JSONGenerator::ObjectSP, dump the string representation of the object into a ostringstream, and then binary escape the ostringstream. We end up with the original ObjectSP dictionary, the ostringstream print of it, and the escaped std::string copy of it. Then we pass that to SendPacket which may create a compressed std::string of it. This patch frees those objects as soon as they are no longer needed, so our peak memory use is limited to a narrower window.
In the future I want to add a JSONGenerator::DumpEscaped() method that formats its output following the binary escape protocol. Every packet that sends JSON responses must escape it before sending, so there's no point in even generating the un-escaped version in the first place. It forces us to always have two copies of the string in heap for at least a little while.
clear doesn't do what you think it does, it modifies the state flag which isn't relevant here.