java虚拟机真正调优的目的:减少full gc的次数,以及它的执行时间
减少STW(StopWorld):停止整个事件
垃圾收集线程都是后台线程。用户在操作的过程中可能突然卡顿了一下,然后又回归正常了,可能就是gc了一下。影响系统网站性能,影响用户体验。
为什么Java虚拟机要有STW?
- 如果我们没有STW,gc会一直顺着局部变量一直找下去,因为现在没有STW,所以在gc的过程中,这个线程可能就执行结束了,意味着都会出栈,但是math对应的局部变量对应的在堆中还没有销毁,对象是gc才会把它干掉,这时候这些没有被引用的对象就会变成垃圾,那么gc在重新检查这些对象的过程中,那程序就不太好设计和实现,它的状态是不断在变化的,有可能是垃圾,也有可能是非垃圾,那如果一直这样检查的话,程序就执行不完了,所以在整个gc回收过程中,就STW,停掉线程,快速做完,做完之后再次回复线程的执行。
垃圾回收器
案例1在一个公司,在大型的促销活动类似双11的活动,这些网站就会频繁的做full gc,那么肯定会影响网站的性能,
1秒之后,线程就结束了,order就不在了,但是new 的对象还在堆内存空间里,gc root根没有了(局部变量没有了),那么new Order就变为垃圾对象了。但是有些线程执行的比较慢,在第13秒或者14秒运行不完,所以伊甸园区就有可能满了,就会触发minor gc、full gc,就会触发STW,这些对象就会被移动到Survivor区,s0区100M,但是一个对象有60M,所以就会发生下面的。老年代也承受不了。
能否对JVM调优,让其几乎不发生full gc?
高并发案例
- 把年轻代内存分配大一点,这样这些对象就会被放到Survivor区,但是不会超过它的内存,就不会放到伊甸园区,这样触发minor gc的时候就把这些对象回收了。最终这些垃圾对象在年轻代就被回收掉了,full gc的执行时间比较长,所以要尽量避免full gc。
只要消息还没有存到及持久化到磁盘中去,就不会被判定为垃圾,
假设伊甸园区有30g,这时候触发minor gc执行就不快了,所以是需要优化的。客户端发消息,如果没有及时返回的话,所以可能会超时,发送失败,重新发送。
当gc的时候会导致大量的客户端请求超时。
minor gc也需要优化。每次minor gc的时候只回收一小块,边使用边回收。
G1收集器
它每次在回首的过程中,它会计算计算这块空间的时间堆,它会计算我这边已经有2个g的空间被占用了,它会计算这个空间回收需要多久呢,假如是50ms,那么他不会立即回收,那么就会到3个g,计算为100ms,就会开始回收。
minor gc频繁一点没有关系,比一次听很长时间好很多。
到3个g,计算为100ms,就会开始回收。



