SPARK-2711. Create a ShuffleMemoryManager to track memory for all spilling collections

This tracks memory properly if there are multiple spilling collections in the same task (which was a problem before), and also implements an algorithm that lets each thread grow up to 1 / 2N of the memory pool (where N is the number of threads) before spilling, which avoids an inefficiency with small spills we had before (some threads would spill many times at 0-1 MB because the pool was allocated elsewhere).
This doesn't say what we return if acquire was successful (I'm assuming the number of bytes acquired). Maybe add this to the first sentence:

"Try to acquire up to numBytes memory for the current thread **_and return numBytes_**, or return 0 if..."