分享
HG 堆外内存管理 - 调研
输入“/”快速插入内容
HG 堆外内存管理 - 调研
用户6445
用户2731
2024年6月21日创建
36
Netty 高效内存管理模型
可以参考:
Netty内存管理调研
Spark 「钨丝计划」(Tungsten)内存管理器
众所周知,Spark 架构上分为 Driver 和 Executor,
•
Driver 为主控进程,负责创建 Spark 上下文,提交 Spark 作业(Job),并将作业转化为计算任务 (Task),在各个Executor 进程间协调任务的调度。
•
Executor 负责计算逻辑,上报自身状态给 ApplicationMaster,计算结果返回给 Driver,为持久化 RDD 提供功能。
Spark 的内存管理主要集中在 Executor 上。分为堆内和堆外内存两部分进行管理。
Spark 内存管理模型
Spark 实现了一种与操作系统内存页非常相似的数据结构
MemoryBlock
,巧妙地将堆内和堆外内存页统一抽象封装,并用页表 (pageTable) 管理每个 Task 申请到的内存页。
即:Tungsten 对执行内存的使用进行了一步的抽象,这样在 Spark 的 Shuffle 过程中无需关心数据具体存储在堆内还是堆外。
每个内存页用一个
MemoryBlock
来定义
,并用
Object obj
和
long offset
这两个变量统一标识一个内存页在系统内存中的地址。
•
堆内的
MemoryBlock
是以
long 型数组
的形式分配的内存,其
obj
的值为是这个数组的对象引用,
offset
是 long 型数组的在 JVM 中的初始偏移地址,两者配合使用可以定位这个数组在堆内的
绝对地址
;
•
堆外的
MemoryBlock
是直接申请到的内存块,其
obj
为 null,
offset
是这个内存块在系统内存中的
64 位绝对地址
。
Tungsten 页式管理下的所有内存用 64 位的
逻辑地址
表示,由页号和页内偏移量组成:
•
页号:占 13 位,唯一标识一个内存页,Spark 在申请内存页之前要先申请空闲页号。
•
页内偏移量:占 51 位,是在使用内存页存储数据时,数据在页内的偏移地址。
有了统一的寻址方式,Spark 可以用 64 位逻辑地址的指针定位到堆内或堆外的内存,整个 Shuffle Write 排序的过程只需要对指针进行排序,并且无需反序列化,整个过程非常高效,对于内存访问效率和 CPU 使用效率带来了明显的提升。
Spark 把内存
分为三个板块
:「存储内存」、「
执行
内存」和「其他内存」。Spark 采用名为「统一内存管理」 的机制,主要思想是:
存储内存和执行内存共享同一块空间,可以动态占用对方的空闲区域。
堆内内存部分如下图所示:
堆外内存部分如下图所示: