 <p>The short answer is: you use a generational garbage collector. </p> <p>Except that most modern Java implementations<sup>1</sup> use a generational collector <em>by default</em>. In other words, you (the programmer) don't need to deal with the problem because it is already dealt with.</p> <p>The only situation where you might run into fragmentation is if you have mis-tuned the low-pause collector and it has fallen back to doing a "stop the world" full collection. At that point, you might be using a non-compacting collector, and fragmentation might ensue. But the solution there is to adjust the tuning (or the application, or the heap size) to avoid getting into that situation.</p> <hr> <p><sup>1 - Some really old Java implementations used primitive mark-sweep collectors. But they are long gone.</sup></p>