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

为什么Chrome中调用Math.random()会产生需GC回收的内存分配?

技术原理说明

98版本之前的Chrome/Edge(基于V8引擎)确实存在该现象,核心原因是旧版V8对Math.random的返回值优化不足:

  • V8的堆内存分配类型中存在HeapNumber类,用于存储无法直接存放在栈/对象属性槽中的浮点数。旧版Math.random的内置实现未被JIT编译器完全内联优化时,返回的随机浮点数会被封装为HeapNumber对象分配到年轻代堆中,单次调用约产生16字节的堆内存占用。
  • 测试代码中给obj.value赋值时,旧版V8未对该属性做原始值存储优化,每次赋值都会把新的HeapNumber挂载到对象属性上,旧的HeapNumber变为无引用垃圾等待回收,高频调用时就会出现典型的年轻代GC锯齿波动。
  • Firefox的SpiderMonkey引擎默认对小浮点数采用NaN装箱技术,可直接把浮点数存在属性槽中无需堆分配,因此不会产生额外GC压力。
证伪依据

可通过以下方式验证结论:

  • 将Chrome/Edge升级到98及以上版本重新测试,该场景下的GC波动会完全消失。V8团队已完成Math.random的内联优化,返回值直接作为原始浮点数存储,不会产生堆分配。
  • 对测试代码添加预热逻辑,先循环调用test函数10万次让JIT完成优化编译,再录制性能面板,可观测到GC次数大幅下降。
  • 用Chrome命令行参数--trace-gc运行测试,日志会显示回收的均为年轻代临时对象,总回收大小和Math.random的调用次数完全对应。
V8相关优化记录

该问题的优化补丁已于2021年11月合并到V8主干,对应Chrome 98正式版开始生效,优化后Math.random的调用无任何堆内存分配,性能提升约30%。

补充优化方案

除采用crypto.getRandomValues预生成随机数数组的方案外,还可根据业务场景选择:

  • 升级浏览器版本到Chrome 98/Edge 98及以上,直接解决问题
  • 实现随机数缓冲池,一次性生成足够的随机数存放在数组中,用完后再批量生成,降低分配频率

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:15:04