我已经实现了v8的垃圾回收回调(序言和结语),并记录了垃圾回收所花费的时间以及每种类型的计数。我在v8上阅读的所有内容都谈到了主要的GC(标记/扫描/紧凑)和次要的GC(清除)。但是还有另外两种类型,它们都会生成回调。从v8代码:
enum GCType {
kGCTypeScavenge = 1 << 0,
kGCTypeMarkSweepCompact = 1 << 1,
kGCTypeIncrementalMarking = 1 << 2,
kGCTypeProcessWeakCallbacks = 1 << 3,
kGCTypeAll = kGCTypeScavenge | kGCTypeMarkSweepCompact |
kGCTypeIncrementalMarking | kGCTypeProcessWeakCallbacks
};
关于IncrementalMarking和ProcessWeakCallbacks的奇怪之处在于,它们的回调总是被调用与MarkSweepCompact回调完全相同的次数。
我的问题是什么是IncrementalMarking和ProcessWeakCallbacks垃圾回收?而且,为什么它们总是被调用与MarkSweepCompact垃圾收集相同的次数(应该将它们视为该收集类型的一部分)?
(这里是V8开发人员。)是的,“ IncrementalMarking”和“ ProcessWeakCallbacks”不是GC的类型,而是主要GC周期的阶段。 (我不知道为什么这个枚举恰巧被称为GCType
,可能是出于历史原因。)
我正在记录垃圾收集所花费的时间以及每种类型的计数
请注意,GC回调既不打算也不适合进行时间测量。特别是,增量标记(顾名思义)发生在许多微小的增量步骤中,但是在这些步骤中的第一个发生之前,您只能获得一次回调。在此之后,将交替执行增量标记步骤和程序执行,直到完成标记为止。
[另外,请注意,该团队正在努力将GC的尽可能多的工作移至后台线程,这提出了整个问题,即“花了多少时间?”有点不确定。
出于离线调查目的,最好的选择是--trace-gc
标志,它应提供准确而完整的计时信息。
对于在线簿记(截至V8 garbage collector callbacks for measuring GC activity,另请参见我的详细答案),恐怕没有好的解决方案。