开发者概览

VeloxDynamicSizingOffheap

qianmoQqianmoQ· 更新于 2026-10-02· 阅读 3 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

动态堆外内存大小调整

Gluten 需要同时设置堆内和堆外内存大小,这会初始化不同的内存布局。若这些设置配置不当,可能导致性能下降。

为解决此问题,动态堆外内存大小调整是一项用于简化该过程的实验性功能。请注意,启用后,用户定义的 Spark 堆外内存设置(spark.memory.offHeap.enabled、spark.memory.offHeap.size)将不再生效,Velox 会将堆内内存大小作为其内存大小。要启用此功能,用户需要在 Spark 配置中添加如下配置项:

--conf spark.gluten.memory.dynamic.offHeap.sizing.enabled=true

详细实现

要理解这些细节,首先需要掌握 JVM 内存管理的基础知识。关于 JVM 内部机制的资料有很多:

总体而言,该功能的工作方式如下:

  • Spark 首先尝试基于堆内大小来分配内存。请注意,最大内存大小由 spark.executor.memory 控制。
  • 当 Velox 尝试分配内存时,Gluten 会尝试从系统内存中进行分配,并在内存分配器中记录该操作。
  • 如果内存充足,分配将正常进行。
  • 如果内存不足,Spark 会执行垃圾回收(GC)以释放堆内内存,从而让 Velox 能够分配内存。
  • 如果 GC 之后内存仍然不足,Spark 会报告内存溢出(OOM)问题。
  • MaxHeapFreeRatio 和 MinHeapFreeRatio 参数用于配置 Spark JVM 进程的最大/最小堆大小。请注意,这两个参数从 JDK-11 起才可用。

随后,我们会强制执行一个总内存配额,该配额等于 Java 堆中已提交(committed)和使用中(in-use)内存之和(通过 Runtime.getRuntime().totalMemory() 获取)加上 TreeMemoryConsumer 中跟踪的堆外内存。如果某次分配超过这个已提交的总内存,分配将失败并触发 OOM。

通过这一变更,“配额检查”会在 Gluten 收到内存分配请求时执行。实际上,这意味着即使堆外使用量已经足以导致分配失败,Java 代码仍可能在堆内配额范围内超额订阅内存。

局限性

该功能目前处于开发的初步阶段,将在后续更新中持续改进。

评论

登录后参与评论

正在加载评论…