1.垃圾回收器
1.1.对象可以在被需要时创建,不再使用时由JVM自动回收
1.2.GC是查找不再使用的对象,然后回收这些对象相关内存的过程
1.2.1.找到不使用的对象、回收其内存、压缩堆内存
1.3.优化垃圾回收器比跟踪指针引起的bug要容易得多(且耗时更少)
1.4.VM必须定期搜索堆中不使用的对象
1.4.1.从GC根(GC root)对象开始搜索,GC根是可以从堆外被访问的对象,主要包括线程栈和系统类
1.4.2.当GC算法找到不使用的对象时,JVM会回收这些对象占用的内存,并将这些内存分配给其他对象
2.垃圾回收器运行多个线程
2.1.一组执行应用程序逻辑,通常被称为mutator线程
2.1.1.作为应用程序逻辑的一部分会改变对象
2.2.另一组执行GC,当GC线程跟踪对象引用(用于回收对象)或者在内存中移动对象时,它们必须确保应用程序线程不使用这些对象
2.3.所有线程都停止运行的停顿被称为STW停顿(stop-the-world pause)
2.3.1.尽量减少这些停顿是优化GC的重中之重
3.垃圾回收器分代
3.1.分代理由
3.1.1.大量对象(有时甚至是大多数对象)是临时对象
3.1.2.很多对象的使用时间很短
3.2.老年代
3.2.1.old generation或tenured generation
3.2.2.Full GC
3.2.2.1.一般会造成应用程序线程较长时间的停顿
3.3.新生代
3.3.1.young generation
3.3.2.只是整个堆的一部分
3.3.2.1.对象首先在新生代中分配
3.3.2.2.比处理整个堆要快
3.3.3.Eden空间
3.3.3.1.占据了新生代的绝大多数空间
3.3.3.2.最初对象会被分配到Eden空间
3.3.3.3.不再使用的对象被丢弃
3.3.3.4.仍在使用的对象被移动到一个Survivor空间或者晋升到老年代
3.3.4.Survivor空间
3.3.4.1.在回收结束时,Eden空间和一个Survivor空间被清空,新生代中剩余的对象都被压缩到另一个Survivor空间中
3.3.5.Minor GC
3.3.5.1.Young GC
3.3.5.2.当新生代被填满时,垃圾回收器会停止所有的应用程序线程,并清空新生代
3.3.5.3.不再使用的对象被丢弃
3.3.5.4.仍在使用的对象被移到其他地方
4.并发回收器
4.1.concurrent collector
4.2.低停顿(low-pause)回收器
4.3.无停顿(pauseless)回收器
4.4.查找的代码可以在不停止应用程序线程的情况下运行
4.5.代价是应用程序总体上使用更多的CPU时间
4.5.1.避免长时间停顿是以消耗额外的CPU周期为代价的
4.6.更难优化以达到最佳性能
5.选型
5.1.单个请求会受停顿时间的影响,尤其是Full GC时较长时间的停顿
5.1.1.减少停顿对响应时间的影响,那么并发回收器可能更合适
5.2.如果平均响应时间比异常值(例如第90百分位响应时间)更重要
5.2.1.并发回收器可能会产生更好的结果
6.GC算法
6.1.Serial垃圾回收器
6.1.1.最简单的回收器
6.1.2.在只有一个CPU可用且额外的GC线程会干扰应用程序的情况下使用(而且是默认的)
6.1.2.1.只有一个核心(甚至是以两个CPU形式出现的超线程核心)的虚拟机和Docker容器让这个算法又有了使用的意义
6.1.3.使用单线程来处理堆
6.1.3.1.处理堆时会停止所有的应用程序线程(不管是Minor GC还是Full GC)
6.1.3.2.在Full GC期间,它将完全压缩老年代
6.1.4.-XX:+UseSerialGC标志可以开启
6.1.5.-XX:-UseSerialGC并不会禁用
6.1.5.1.禁用需要设定另外一个垃圾回收器
6.2.CMS垃圾回收器
6.2.1.第一个并发垃圾回收器
6.2.1.1.JDK 8中相当流行
6.2.1.2.自JDK 11被正式废弃,而且不鼓励在JDK 8中使用
6.2.2.会在Minor GC的过程中停止所有的应用程序线程
6.2.3.主要缺陷是它不能在后台处理过程中压缩堆
6.2.4.-XX:+UseConcMarkSweepGC标志开启
6.2.4.1.默认值是false
6.3.Throughput垃圾回收器
6.3.1.并行回收器(parallel collector)
6.3.2.JDK8中任何有两个或者多个CPU的64位机器的默认垃圾回收器
6.3.3.-XX:+UseParallelGC标志
6.3.4.-XX:+UseParallelOldGC标志
6.3.4.1.已经过时了
6.3.4.2.可以禁用这个标志,只对新生代进行并行回收
6.4.G1 GC
6.4.1.垃圾优先垃圾回收器
6.4.2.使用并发回收策略来以最小的停顿回收堆
6.4.3.JDK 11和之后版本的默认垃圾回收器
6.4.4.-XX:+UseG1GC标志开启