垃圾回收
垃圾回收算法:
标记-清除法:当发现需要回收的内容时,标记并直接清除。
缺点:需要遍历全堆,复杂度高,并且会带来内存碎片等问题
标记-整理法:将不需要回收的内容标记并整理到一起,然后清除剩下的部分
优缺点:没有内存碎片问题;但是如果存活的多,会产生多次搬运,降低效率。
复制法:将内存分两块,每次将存活的对象搬运到另一块,并清理这一块。
优缺点:清理容易,但是内存利用率低(需要占用双倍内存)。
分代垃圾回收:现在普遍虚拟机都采用
新创建的对象一般都是生命周期较短的,分代可以优先回收这些。具体的算法根据实际情况使用上面的。
内存分新生代和老年代,新生代再分为3区,eden 区和 from 区、to 区。新建的对象放在新生代的 eden 区;当 eden 区满了,对 eden 进行 minor gc,把存活的搬入 to 区,存活的对象年龄加1并且交换 from to;当 eden 再次满了,对 eden 和 from 区进行 minor gc,将 eden 区和 from 区存活的搬入 to 区,存活的对象年龄加1并且交换 from to; 重复2、3步,直到一定次数(最大为15次,即4bit,如果内存不足,可能不到15次)后,将仍然存活在 from 区的内容搬入老年区;老年区满了以后,先尝试进行 minor gc ,如果空间还不足,则进行 full gc,是最慢的。
minor gc 会引发 STW(stop the world),暂停其它用户的线程,等垃圾回收结束,用户线程才恢复运行。
四种引用:
垃圾回收器:
1.串行
串行垃圾收集器,是指使用单线程进行垃圾回收,垃圾回收时,只有一个线程在工作,并且java应用中的所有线程都要暂停,等待垃圾回收的完成。这种现象称之为STW(Stop-The-World)。
对于交互性较强的应用而言,这种垃圾收集器是不能够接受的。一般在Javaweb应用中是不会采用该收集器的。
2.并行
并行垃圾收集器在串行垃圾收集器的基础之上做了改进,将单线程改为了多线程进行垃圾回收,这样可以缩短垃圾回收的时间。
当然了,并行垃圾收集器在收集的过程中也会暂停应用程序,这个和串行垃圾回收器是一样的,只是并行执行垃圾回收,速度更快些,暂停的时间更短一些。
ParNew垃圾收集器:
ParNew垃圾收集器是工作在年轻代上的,只是将串行的垃圾收集器改为了并行。
通过 -XX:+UseParNewGC 参数设置年轻代使用ParNew回收器,老年代使用的依然是串行收集器。
ParallelGC垃圾收集器:
ParallelGC 收集器工作机制和ParNewGC收集器一样,只是在此基础之上,新增了两个和系统吞吐量相关的参数,使得其使用起来更加的灵活和高效。
3.CMS垃圾收集器
CMS全称 Concurrent Mark Sweep,是一款并发的、使用标记-清除算法的垃圾回收器,该回收器是针对老年代垃圾回收的,通过参数-XX:+UseConcMarkSweepGC进行设置。
4.G1
GC调优:调优跟应用、环境有关,没有放之四海而皆准的法则
确定目标:
【低延迟】还是【高吞吐量】,选择合适的回收器
CMS,G1,ZGC
ParallelGC
Zing
最快的GC是不发生GC:
新生代:
新生代设置成能容纳所有【并发量 *(请求-响应)】的数据
幸存区大到能保留【当前活跃对象 + 需要晋升对象】
晋升阈值配置得当,让长时间存活对象尽快晋升
老年代:
G1性能调优:G1 的设计原则就是简化JVM性能调优,开发人员只需要简单的三步即可完成调优:
1. 第一步,开启G1垃圾收集器
2. 第二步,设置堆的最大内存
3. 第三步,设置最大的停顿时间
G1中提供了三种模式垃圾回收模式,Young GC、Mixed GC 和 Full GC,在不同的条件下被触发。
G1垃圾收集器相对比其他收集器而言,最大的区别在于它取消了年轻代、老年代的物理划分,取而代之的是将堆划分为若干个区域(Region),这些区域中包含了有逻辑上的年轻代、老年代区域。
对于G1垃圾收集器优化建议: