We first present our adaptive system that allow garbage-collected applications, working both independently and in conjunction with other executing applications, to adjust and optimize its memory usage. As we show using a series of diverse workloads, this system improves overall throughput by up to a factor of 4.5 without ever degrading performance. We also descibe how operating systems can be modified to better account for this new application behavior. By improving how the OS manages memory for concurrently executing applications, we can make application performance more predictable and decrease throughput time. Taken together, this work shows why memory management must change in multiprogramming, multi-core environments and how these changes can be made.