In this paper, we address this limitation with techniques that attempt to automatically unload dead or infrequently used native code to reduce the memory footprint of a compile-only JVM. We describe a number of profile-based strategies that identify unloading candidates. Our empirical evaluation, using a number of common benchmarks, indicates that dynamic code unloading can reduce code size significantly with negligible overhead. When memory is highly constrained, this reduction translates into significant execution time benefits for the benchmarks, JVM, and JVM configuration that we investigated.