Java--JVM总结

在堆中,新生代主要存放的是哪些很快就会被GC回收掉的或者不是特别大的对象(这个大就要看你是否设置了-XX:PretenureSizeThreshold 参数了)。新生代采用的复制算法,即将新生代分为3个区:较大的Eden和两个较小的Survivor(默认的Eden:Survivor = 8:1)。发生在新生代的GC为Minor GC 。在Minor GC时会将新生代中还存活着的对象复制进一个Survivor中,然后对Eden和另一个Survivor进行清理。所以,平常可用的新生代大小为Eden的大小+一个Survivor的大小。

老年代则是存放那些在程序中经历了好几次回收仍然还活着或者特别大的对象(这个大就要看你是否设置了-XX:PretenureSizeThreshold 参数了)。老年代采用的是标记-清除或者标记-整理算法,这两个算法主要看虚拟机采用的哪个收集器,两种算法的区别是:标记-清除可能会产生大量连续的内存碎片。在老年代中的GC则为Major GC。Major GC和Full GC会造成stop-the-world。

那么什么情况下,新生代的对象会进入老年代呢?

首先就是分配担保机制:当Minor GC时,新生代存活的对象大于Survivor的大小时,这时一个Survivor装不下它们,那么它们就会进入老年代。

还有其他的情况:如果设置了-XX:PretenureSizeThreshold3M 那么大于3M的对象就会直接就进入老年代。

还有,在新生代的每一次Minor GC 都会给在新生代中的对象+1岁,默认到15岁时就会从新生代进入老年代,可以通过-XX:MaxTenuringThreshold来设置这个临界点。

相比较而言,在老年代中的对象比新生代中的对象不易回收许多。

JVM的方法区,也被称为永久代。在这里都是放着一些被虚拟机加载的类信息,静态变量,常量等数据。这个区中的东西比老年代和新生代更不容易回收。

猜你喜欢

转载自blog.csdn.net/lulu950817/article/details/79764427