StackOverflow上面给出的解释是:
The reason for the HotSpot JVM's two survivor spaces is to reduce the need to deal with fragmentation. New objects are allocated in eden space. All well and good. When that's full, you need a GC, so kill stale objects and move live ones to a survivor space, where they can mature for a while before being promoted to the old generation. Still good so far. The next time we run out of eden space, though, we have a conundrum. The next GC comes along and clears out some space in both eden and our survivor space, but the spaces aren't contiguous. So is it better to
- Try to fit the survivors from eden into the holes in the survivor space that were cleared by the GC?
- Shift all the objects in the survivor space down to eliminate the fragmentation, and then move the survivors into it?
- Just say "screw it, we're moving everything around anyway," and copy all of the survivors from both spaces into a completely separate space--the second survivor space--thus leaving you with a clean eden and survivor space where you can repeat the sequence on the next GC?
Sun's answer to the question is obvious.
对于如何达到“无碎片”的目的,理解上可能有些困难,下面我把新生代回收机制详细解释一下:
注意,两个survivor是交替使用的,在任意一个时刻,必定有一个survivor为空,一个survivor中存放着对象(连续存放,无碎片)。回收过程如下:
S1、GC,将eden中的live对象放入当前不为空的survivor中,将eden中的非live对象回收。如果survivor满了,下次回收执行S2;如果survivor未满,下次回收仍然以S1的方式回收;
S2、GC,将eden和存放着对象的survivor中的live对象放入当前为空的survivor中,将非live对象回收。
可以看到,上述的新生代回收机制保证了一个survivor为空,另一个非空survivor中无碎片。
在执行一定次数的minor GC后,会通过Full GC将新生代的survivor中的对象移入老年代。
对于理解GC的整个机制,推荐一篇非常好的文章:http://www.cubrid.org/blog/dev-platform/understanding-java-garbage-collection/