Garbage collectors used in embedded systems such as Personal Java and Inferno or in operating systems such as SPIN must operate with limited resources and minimize their impact on application performance. Consequently, they must maintain short real-time pauses, low overhead, and a small memory footprint. Most garbage collectors, including the Treadmill algorithm, are inadequate because they sacrifice space for time. We have implemented a new Treadmill variant that provides good memory utilization by using real-time page-level management techniques that reduce fragmentation. A page-wise collection is used to locate pages of free memory, which are then dynamically reassigned between free lists as needed. Virtual memory is used to dynamically remap free pages into continuous ranges, and objects are allocated from under-utilized pages when needed. Finally, the use of header compaction and arbitrary free-list sizes reduces internal fragmentation. Our experiments demonstrate that we have substantially improved memory utilization without compromising latency or overhead, and that the new collector performs very well for SPIN's workloads and regular Modula-3 programs.