You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将JS对象排除在V8 GC标记扫描之外?

大型静态JS对象的V8 GC优化问题

我有一个包含大量子对象的JS对象{},相当于一个大型嵌入式键值存储。出于性能考虑(访问延迟至关重要),它需要常驻内存。该对象在启动时加载一次后保持静态,但应用在Major GC阶段出现严重卡顿,推测是GC需要遍历这个庞大的引用树所致。我希望能将其排除在GC扫描之外。

需要明确两个核心问题:

  • 如何验证该对象是否确实被Major GC扫描?
  • 若无法排除扫描,如何加速GC的扫描过程?

我曾尝试通过原生扩展中的"Eternal"句柄将父对象标记为Eternal,期望GC算法能跳过这个庞大的引用树,但对象虽变为常驻内存,Mark-Sweep阶段的耗时并未明显降低(或小测试场景中无法观测到差异)。已确认该对象及其子对象不会被回收,但推测它们仍会被GC扫描。

是否存在其他高级技巧可将该对象"隐藏"于GC扫描范围之外?我还考虑过将对象序列化到外部内存(如Buffer),访问时再反序列化,但担心这种方式会带来过高的访问延迟。


3月14日更新:
附上通过--trace-gc-nvp收集的重度GC日志,重点关注GC触发时的pause时间以及mark.main=1368.6和mark.main=564.0字段(代表主线程在标记阶段的耗时):

[18726:0x7fe875a16000]   549342 ms: pause=1421.3 mutator=480.8 gc=ms reduce_memory=1 time_to_safepoint=0.00 heap.prologue=0.00 heap.embedder_tracing_epilogue=0.00 heap.epilogue=0.00 heap.epilogue.reduce_new_space=0.04 heap.external.prologue=0.0 heap.external.epilogue=0.0 heap.external.weak_global_handles=1.2 clear=29 clear.dependent_code=0.0 clear.maps=0.6 clear.slots_buffer=0.0 clear.string_table=25.4 clear.weak_collections=0.6 clear.weak_lists=0.8 clear.weak_references=3.3 complete.sweep_array_buffers=0.0 epilogue=0.0 evacuate=11.9 evacuate.candidates=0.0 evacuate.clean_up=0.0 evacuate.copy=0.4 evacuate.prologue=0.0 evacuate.epilogue=0.0 evacuate.rebalance=0.0 evacuate.update_pointers=11.4 evacuate.update_pointers.to_new_roots=10.5 evacuate.update_pointers.slots.main=0.9 evacuate.update_pointers.weak=0.0 finish=0.5 finish.sweep_array_buffers=0.4 mark=1373.4 mark.finish_incremental=0.0 mark.roots=4.2 mark.main=1368.6 mark.weak_closure=0.5 mark.weak_closure.ephemeron=0.0 mark.weak_closure.ephemeron.marking=0.1 mark.weak_closure.ephemeron.linear=0.0 mark.weak_closure.weak_handles=0.2 mark.weak_closure.weak_roots=0.1 mark.weak_closure.harmony=0.0 mark.embedder_prologue=0.0 mark.embedder_tracing=0.0 prologue=0.3 sweep=1.2 sweep.code=0.0 sweep.map=0.0 sweep.old=0.8 incremental=0.0 incremental.finalize=0.0 incremental.finalize.body=0.0 incremental.finalize.external.prologue=0.0 incremental.finalize.external.epilogue=0.0 incremental.layout_change=0.0 incremental.sweep_array_buffers=0.0 incremental.sweeping=4.3 incremental.embedder_prologue=0.0 incremental.embedder_tracing=0.0 incremental_wrapper_tracing_longest_step=0.0 incremental_finalize_longest_step=0.0 incremental_finalize_steps_count=0 incremental_longest_step=0.0 incremental_steps_count=0 incremental_marking_throughput=454557 incremental_walltime_duration=0 background.mark=5465.6 background.sweep=0.0 background.evacuate.copy=0.0 background.evacuate.update_pointers=0.1 background.unmapper=0.0 unmapper=0.0 total_size_before=1220256112 total_size_after=1212858824 holes_size_before=11506904 holes_size_after=249456 allocated=3530448 promoted=9216 semi_space_copied=0 nodes_died_in_new=0 nodes_copied_in_new=0 nodes_promoted=0 promotion_ratio=0.3% average_survival_ratio=0.2% promotion_rate=74.4% semi_space_copy_rate=0.0% new_space_allocation_throughput=6877.3 unmapper_chunks=60 compaction_speed=27514
[18726:0x7fe875a16000]   550056 ms: pause=713.6 mutator=0.8 gc=ms reduce_memory=1 time_to_safepoint=0.00 heap.prologue=0.00 heap.embedder_tracing_epilogue=0.00 heap.epilogue=0.00 heap.epilogue.reduce_new_space=0.01 heap.external.prologue=0.0 heap.external.epilogue=0.0 heap.external.weak_global_handles=0.0 clear=9 clear.dependent_code=0.0 clear.maps=0.5 clear.slots_buffer=0.0 clear.string_table=6.7 clear.weak_collections=0.5 clear.weak_lists=0.1 clear.weak_references=2.2 complete.sweep_array_buffers=0.0 epilogue=0.0 evacuate=20.5 evacuate.candidates=0.0 evacuate.clean_up=0.0 evacuate.copy=2.2 evacuate.prologue=0.0 evacuate.epilogue=0.0 evacuate.rebalance=0.0 evacuate.update_pointers=18.3 evacuate.update_pointers.to_new_roots=15.3 evacuate.update_pointers.slots.main=3.0 evacuate.update_pointers.weak=0.0 finish=0.0 finish.sweep_array_buffers=0.0 mark=565.3 mark.finish_incremental=0.0 mark.roots=0.6 mark.main=564.0 mark.weak_closure=0.7 mark.weak_closure.ephemeron=0.0 mark.weak_closure.ephemeron.marking=0.0 mark.weak_closure.ephemeron.linear=0.0 mark.weak_closure.weak_handles=0.3 mark.weak_closure.weak_roots=0.1 mark.weak_closure.harmony=0.0 mark.embedder_prologue=0.0 mark.embedder_tracing=0.0 prologue=0.0 sweep=1.1 sweep.code=0.0 sweep.map=0.0 sweep.old=0.7 incremental=0.0 incremental.finalize=0.0 incremental.finalize.body=0.0 incremental.finalize.external.prologue=0.0 incremental.finalize.external.epilogue=0.0 incremental.layout_change=0.0 incremental.sweep_array_buffers=0.0 incremental.sweeping=4.3 incremental.embedder_prologue=0.0 incremental.embedder_tracing=0.0 incremental_wrapper_tracing_longest_step=0.0 incremental_finalize_longest_step=0.0 incremental_finalize_steps_count=0 incremental_longest_step=0.0 incremental_steps_count=0 incremental_marking_throughput=454557 incremental_walltime_duration=0 background.mark=2247.3 background.sweep=0.0 background.evacuate.copy=0.0 background.evacuate.update_pointers=4.5 background.unmapper=0.4 unmapper=0.0 total_size_before=1212842032 total_size_after=1212769512 holes_size_before=15545968 holes_size_after=276432 allocated=18446744073709534824 promoted=0 semi_space_copied=0 nodes_died_in_new=0 nodes_copied_in_new=0 nodes_promoted=0 promotion_ratio=0.3% average_survival_ratio=0.2% promotion_rate=74.4% semi_space_copy_rate=0.0% new_space_allocation_throughput=6871.3 unmapper_chunks=60 compaction_speed=196592

此外,我尝试了一种将JS对象转换为Buffer表示的方案,本质是把对象从Old Space移到External Space(推测处于GC扫描范围之外),确实带来了GC性能改善:

[74946:0x7f9ef0216000]   417345 ms: pause=416.4 mutator=161.3 gc=ms reduce_memory=1 time_to_safepoint=0.00 heap.prologue=0.00 heap.embedder_tracing_epilogue=0.00 heap.epilogue=0.00 heap.epilogue.reduce_new_space=0.01 heap.external.prologue=0.0 heap.external.epilogue=0.0 heap.external.weak_global_handles=0.0 clear=8 clear.dependent_code=0.0 clear.maps=0.4 clear.slots_buffer=0.0 clear.string_table=6.1 clear.weak_collections=0.5 clear.weak_lists=0.1 clear.weak_references=1.9 complete.sweep_array_buffers=0.0 epilogue=0.0 evacuate=35.2 evacuate.candidates=0.0 evacuate.clean_up=0.0 evacuate.copy=8.1 evacuate.prologue=0.0 evacuate.epilogue=0.1 evacuate.rebalance=0.0 evacuate.update_pointers=26.9 evacuate.update_pointers.to_new_roots=11.5 evacuate.update_pointers.slots.main=15.4 evacuate.update_pointers.weak=0.0 finish=4.2 finish.sweep_array_buffers=4.1 mark=364.7 mark.finish_incremental=0.0 mark.roots=0.7 mark.main=363.7 mark.weak_closure=0.4 mark.weak_closure.ephemeron=0.0 mark.weak_closure.ephemeron.marking=0.1 mark.weak_closure.ephemeron.linear=0.0 mark.weak_closure.weak_handles=0.2 mark.weak_closure.weak_roots=0.1 mark.weak_closure.harmony=0.0 mark.embedder_prologue=0.0 mark.embedder_tracing=0.0 prologue=0.1 sweep=1.2 sweep.code=0.0 sweep.map=0.0 sweep.old=0.7 incremental=0.0 incremental.finalize=0.0 incremental.finalize.body=0.0 incremental.finalize.external.prologue=0.0 incremental.finalize.external.epilogue=0.0 incremental.layout_change=0.0 incremental.sweep_array_buffers=0.0 incremental.sweeping=3.5 incremental.embedder_prologue=0.0 incremental.embedder_tracing=0.0 incremental_wrapper_tracing_longest_step=0.0 incremental_finalize_longest_step=0.0 incremental_finalize_steps_count=0 incremental_longest_step=0.0 incremental_steps_count=0 incremental_marking_throughput=600777 incremental_walltime_duration=0 background.mark=1447.7 background.sweep=0.0 background.evacuate.copy=30.7 background.evacuate.update_pointers=57.1 background.unmapper=15.9 unmapper=0.0 total_size_before=1187271352 total_size_after=1184864520 holes_size_before=127885080 holes_size_after=363824 allocated=1147072 promoted=4168 semi_space_copied=0 nodes_died_in_new=0 nodes_copied_in_new=0 nodes_promoted=0 promotion_ratio=0.3% average_survival_ratio=0.8% promotion_rate=34.7% semi_space_copy_rate=0.0% new_space_allocation_throughput=6552.1 unmapper_chunks=11 compaction_speed=260826
[74946:0x7f9ef0216000]   417902 ms: pause=557.0 mutator=0.5 gc=ms reduce_memory=1 time_to_safepoint=0.00 heap.prologue=0.00 heap.embedder_tracing_epilogue=0.00 heap.epilogue=0.00 heap.epilogue.reduce_new_space=0.01 heap.external.prologue=0.0 heap.external.epilogue=0.0 heap.external.weak_global_handles=0.0 clear=8 clear.dependent_code=0.0 clear.maps=0.4 clear.slots_buffer=0.0 clear.string_table=6.4 clear.weak_collections=0.5 clear.weak_lists=0.1 clear.weak_references=1.8 complete.sweep_array_buffers=0.0 epilogue=0.0 evacuate=42.1 evacuate.candidates=0.0 evacuate.clean_up=0.0 evacuate.copy=9.0 evacuate.prologue=0.0 evacuate.epilogue=0.1 evacuate.rebalance=0.0 evacuate.update_pointers=33.0 evacuate.update_pointers.to_new_roots=14.9 evacuate.update_pointers.slots.main=18.1 evacuate.update_pointers.weak=0.0 finish=0.0 finish.sweep_array_buffers=0.0 mark=413.5 mark.finish_incremental=0.0 mark.roots=0.6 mark.main=412.5 mark.weak_closure=0.4 mark.weak_closure.ephemeron=0.0 mark.weak_closure.ephemeron.marking=0.0 mark.weak_closure.ephemeron.linear=0.0 mark.weak_closure.weak_handles=0.2 mark.weak_closure.weak_roots=0.1 mark.weak_closure.harmony=0.0 mark.embedder_prologue=0.0 mark.embedder_tracing=0.0 prologue=0.0 sweep=1.2 sweep.code=0.0 sweep.map=0.0 sweep.old=0.7 incremental=0.0 incremental.finalize=0.0 incremental.finalize.body=0.0 incremental.finalize.external.prologue=0.0 incremental.finalize.external.epilogue=0.0 incremental.layout_change=0.0 incremental.sweep_array_buffers=0.0 incremental.sweeping=3.5 incremental.embedder_prologue=0.0 incremental.embedder_tracing=0.0 incremental_wrapper_tracing_longest_step=0.0 incremental_finalize_longest_step=0.0 incremental_finalize_steps_count=0 incremental_longest_step=0.0 incremental_steps_count=0 incremental_marking_throughput=600777 incremental_walltime_duration=0 background.mark=1642.3 background.sweep=0.0 background.evacuate.copy=34.2 background.evacuate.update_pointers=62.1 background.unmapper=16.2 unmapper=0.0 total_size_before=1184859816 total_size_after=1184749368 holes_size_before=96876512 holes_size_after=478768 allocated=18446744073709546912 promoted=0 semi_space_copied=0 nodes_died_in_new=0 nodes_copied_in_new=0 nodes_promoted=0 promotion_ratio=0.3% average_survival_ratio=0.8% promotion_rate=34.7% semi_space_copy_rate=0.0% new_space_allocation_throughput=6488.6 unmapper_chunks=11 compaction_speed=305301

内容的提问来源于stack exchange,提问作者snowdragon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 05:30:53