堆内存动态分配情况和jvm调优方向
由上图可以看出:
堆中分为新生代(占堆1/3内存)和老年代(占堆2/3内存),
新生代又分为Eden区(占新生代内存的8/10)和survivor区(占新生代内存的2/10),
survivor区又分为from区和to区(各占新生代内存的1/10)
我们知道new出来的对象都是方在堆里面,那么具体在堆里面是怎么样的呢?
1、刚开始new出来的对象放在Eden区
2、等到Eden放满之后,就会进行一次minor gc,清除无效对象并将存活的对象移入from区(第一次minor gc),Eden又可以继续存放对象
3、Eden再次放满之后,再进行minor gc,清除无效对象并将Eden区的存活对象和from区的存活对象一起移入to区,Eden又可以继续存放对象
4、Eden再次放满之后,再进行minor gc,清除无效对象并将Eden区的存活对象和to区的存活对象一起移入from区,Eden又可以继续存放对象
5、之后一直重复3和4的操作,直到from区或者to区中存活对象的年龄超过15岁(每进行一次minor gc后存活对象的年龄加1),在那一次minor gc后会将年龄超过15岁的存活对象移入老年代。(ps:可以通过-XX:MaxTenuringThreshold来设置对象进入老年代的年龄阔值)
6、直到老年代被放满,此时会发生full gc,清除所有区域(包括堆和方法区)的无效对象。(注意:每次发生full gc都会发生“STW”也就是“Stop The Word ”,会暂停其他所有线程。这在浏览器或者客户端就表现为卡顿)
重点:
jvm调优方向:
1、一般来说发生minor gc的时间是非常短的,一般不需要进行调优,但是当发生minor gc的次数非常多的时候才需要进行调优。减少发生minor gc的次数(一般用不到)
2、full gc的速度一般比minor gc慢十倍,而且都会发生STW现象。
3、jvm调优的最终目的有两个:1)减少发生full gc的时间。2)减少发生full gc的次数(最主要的调优方向)