问题:java堆被分成老年代和年轻代,他们有何区别?
根据对象的生命周期的长短把对象分成不同的种类(年轻代,年老代和持久代),并分别进行内存回收, 也就是分代垃圾回收。
什么情况下会触发fullGC,应该如何避免?
1)调用System.gc()方法会触发fullGC,因此,在编码的时候尽量避免调用这个方法;
2)老年代空间不足。由于老年代主要用来存储从年轻代转入的对象,大对象和大数组,因此,为了避免触发fullGC,应该尽量做到让对象在Minor GC阶段被回收,不要创建过大的对象及数组。由于在Minor GC时,只有Survivor区放不下的对象才会被放入老年代,因此只有老年代也放不下才会触发fullGC。所以另一种避免fullGC的方法如下:根据实际情况增大Survivor区,老年代空间或调低触发并发GC(并发垃圾回收)的概率;
3)永久代满。永久代主要存放class相关信息,当永代满的时候,也会触发fullGC。为了避免这种情况的发生,可以增大永久代的空间(-XX:MaxPermSize=16m 设置永久代大小为16MB)。为了避免永久代满引起的fullGC,也可以开启CMS回收永久代选项(+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled)。CMS利用和应用程序线程并发的垃圾回收线程来进行垃圾回收操作。
值得注意的是,java8中已经移除了永久代,新加了一个称为元数据区的native内存区,所以大部分类的元数据都在本地内存中分配。