读Java性能权威指南(第2版)笔记14垃圾回收A
读Java性能权威指南(第2版)笔记14垃圾回收A1。垃圾回收器1。1。对象可以在被需要时创建,不再使用时由JVM自动回收1。2。GC是查找不再使用的对象,然后回收这些对象相关内存的过程1。2。1。找到不使用的对象、回收其内存、压缩堆内存1。3。优化垃圾回收器比跟踪指针引起的bug要容易得多(且耗时更少)1。4。VM必须定期搜索堆中不使用的对象1。4。1。从GC根(GCroot)对象开始搜索,GC根是可以从堆外被访问的对象,主要包括线程栈和系统类1。4。2。当GC算法找到不使用的对象时,JVM会回收这些对象占用的内存,并将这些内存分配给其他对象2。垃圾回收器运行多个线程2。1。一组执行应用程序逻辑,通常被称为mutator线程2。1。1。作为应用程序逻辑的一部分会改变对象2。2。另一组执行GC,当GC线程跟踪对象引用(用于回收对象)或者在内存中移动对象时,它们必须确保应用程序线程不使用这些对象2。3。所有线程都停止运行的停顿被称为STW停顿(stoptheworldpause)2。3。1。尽量减少这些停顿是优化GC的重中之重3。垃圾回收器分代3。1。分代理由3。1。1。大量对象(有时甚至是大多数对象)是临时对象3。1。2。很多对象的使用时间很短3。2。老年代3。2。1。oldgeneration或tenuredgeneration3。2。2。FullGC3。2。2。1。一般会造成应用程序线程较长时间的停顿3。3。新生代3。3。1。younggeneration3。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。MinorGC3。3。5。1。YoungGC3。3。5。2。当新生代被填满时,垃圾回收器会停止所有的应用程序线程,并清空新生代3。3。5。3。不再使用的对象被丢弃3。3。5。4。仍在使用的对象被移到其他地方4。并发回收器4。1。concurrentcollector4。2。低停顿(lowpause)回收器4。3。无停顿(pauseless)回收器4。4。查找的代码可以在不停止应用程序线程的情况下运行4。5。代价是应用程序总体上使用更多的CPU时间4。5。1。避免长时间停顿是以消耗额外的CPU周期为代价的4。6。更难优化以达到最佳性能5。选型5。1。单个请求会受停顿时间的影响,尤其是FullGC时较长时间的停顿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。处理堆时会停止所有的应用程序线程(不管是MinorGC还是FullGC)6。1。3。2。在FullGC期间,它将完全压缩老年代6。1。4。XX:UseSerialGC标志可以开启6。1。5。XX:UseSerialGC并不会禁用6。1。5。1。禁用需要设定另外一个垃圾回收器6。2。CMS垃圾回收器6。2。1。第一个并发垃圾回收器6。2。1。1。JDK8中相当流行6。2。1。2。自JDK11被正式废弃,而且不鼓励在JDK8中使用6。2。2。会在MinorGC的过程中停止所有的应用程序线程6。2。3。主要缺陷是它不能在后台处理过程中压缩堆6。2。4。XX:UseConcMarkSweepGC标志开启6。2。4。1。默认值是false6。3。Throughput垃圾回收器6。3。1。并行回收器(parallelcollector)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。G1GC6。4。1。垃圾优先垃圾回收器6。4。2。使用并发回收策略来以最小的停顿回收堆6。4。3。JDK11和之后版本的默认垃圾回收器6。4。4。XX:UseG1GC标志开启