本系列文章由作者
@hunter129翻译,转载请注明出处。
这是第三章的剩余部分:4.性能度量指标,5.分代收集的基本原理。
性能度量 一些指标用来评估垃圾收集的性能,包括:
吞吐量(Throughput)
一个很长的周期中,除去花费在垃圾收集上的时间占总时间的百分比。
垃圾收集开销(Garbage collection overhead)
与吞吐量相反,这是垃圾收集占总时间的百分比。
(译注:为什么需要两个指标呢?对于并发的垃圾收集算法,垃圾收集的部分任务和应用系统同时运行导致上述两个指标加起来会大于100%)
暂停时间(Pause time)
垃圾收集发生时,应用系统暂停的时间。
收集频率(Frequency of collection)
垃圾收集相对于应用系统运行发生的频率。
占用空间(Footprint)
一种大小的指标,例如堆大小。
反应时间(Promptness)
对象变成垃圾之后到内存可用的时间
一个交互式应用需要较低的暂停时间,反之持续的执行时间对于非交互式应用更加重要。一个实时应用程序要求在垃圾收集中的暂停以及收集器的整个周期拥有较少的抖动。运行在个人计算机或嵌入式设备中的应用可能主要关心小的空间占用。
分代收集使用分代(generational collection)收集技术时,内存分为很多代(generations),分离的存储池存储不同年龄的对象。例如,最通用的配置中有两代:一个用于存放年轻的对象,另一存放年老的对象。
不同的代使用不同的算法执行垃圾收集任务,每个算法会基于本代独特的特征进行优化。分代的垃圾收集基于一种被称为弱分代假设(weak generational hypothesis),它是关于在几种语言(包括java语言)编写的应用程序中观察到的结果:
大部分的分配的对象不会被引用(存活)很长时间,这些对象在年轻的时候就死掉了
年老对象引用年轻对象的情况很少出现
年轻代的收集发生的相对频繁、有效、快速,因为年轻代的空间通常比较小并且有很多的对象都不再被引用。
在年轻代几次收集后仍然生存的对象最终会晋升(promoted)或者被授予(tenured)到年老代。如图1。年老代一般比年轻代大,并且增长的速度很慢。结果是,年老代的收集很少发生,但是会花费更长的时间才能完成。
为年轻代设计的收集算法主要关注在速度方面,因为垃圾收集经常发生。另一方面,在空间方面更有效率的算法管理着年老代,因为年老代占据了大部分的堆空间并且年老代的垃圾密度比较低。