打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Spark Task 内存管理on-heap&off-heap

  我们有类似这样的疑问,在 task 中,shuffle 时使用的内存具体是怎么分配的?是在堆上分配的还是堆外分配的?堆上如何分配、堆外又如何分配?

  这些问题可以通过剖析 TaskMemoryManager 来解决。TaskMemoryManager 用来管理一个 task 的内存,主要涉及申请内存、释放内存及如何表示统一的表示从堆或堆外申请的一块固定大小的连续的内存

  统一的内存块表示 - MemoryBlock

  对于堆内存,分配、释放及对象引用关系都由 JVM 进行管理。new 只是返回一个对象引用,而不是该对象在进程地址空间的地址。堆内存的使用严重依赖 JVM 的 GC 器,对于大内存的使用频繁的 GC 经常会对性能造成很大影响。

  Java 提供的 ByteBuffer.allocateDirect 方法可以分配堆外内存,其分配大小受 MaxDirectMemorySize 配置限制。另一种分配堆外内存的方法就是 Unsafe 的 allocateMemory 方法,相比前者,它完全脱离了 JVM 限制,与 C 中的 malloc 功能一致。这两个方法还有另一个区别:后者返回的是进程空间的实际内存地址,而前者被 ByteBuffer 进行包装。

  堆内内存使用简单,但在使用大内存时其 GC 机制容易影响性能;堆外内存相交于堆内存使用复杂,但精确的内存控制使其更高效。在 Spark 中,很多地方会有大数组大内存的需求,高效的内存使用时必须的,因此 Spark 也提供了堆外内存的支持,以优化 Application 运行性能。

  Spark 封装了 MemoryLocation 来表示一个逻辑内存地址,其定义如下:

  以及 MemoryBlock 来表示一块连续的内存,这块内存可以从堆或对外分配,包含以下成员:

  length:内存块大小

  pageNumber:page id(这块内存又被叫做 page)

  obj:见下文分析

  offset:见下文分析

  接下来我们来看看如何从堆内和堆外申请内存并生成对应的 MemoryBlock 对象。

  申请堆外内存

  Spark 封装了 UnsafeMemoryAllocator 类来分配和释放堆外内存,分配的方法如下:

  其中 Platform.allocateMemory(size) 会调用 Unsafe.allocateMemory 来从堆外分配一块 size 大小的内存并返回其绝对地址。随后,构造并返回 MemoryBlock 对象,需要注意的是,该对象的 obj 成员为 null,offset 成员为该绝对地址

  申请堆内存

  Spark 封装了 HeapMemoryAllocator 类分配和释放堆内存,分配的方法如下:

  总共分为两步:

  以8字节对齐的方式申请长度为 ((size + 7) / 8) 的 long 数组,得到 array

  构造 MemoryBlock 对象,其 obj 成员为 array,offset 成员为 Platform.LONG_ARRAY_OFFSET

  Page table

  在 TaskMemoryManager 有一个如下成员:

  该成员保存着一个 task 所申请的所有 pages(page 即 MemoryBlock),最多可以有8192个。在 TaskMemoryManager#allocatePage(...) 中从堆或堆外分配的 page 会被添加到该 pageTable 中。

  对 page 地址进行统一编码

  通过上面的分析我们知道,page 对应的内存可能来自堆或堆外。但这显然不应该由上层操作者来操心,所以 TaskMemoryManager 提供了只需传入 page 及要访问该 page 上的 offset 就能获得一个 long 型的地址。这样应用者只需操作自该地址起的某一段内存即可,而不用关心这块内存是来自哪。这即是 TaskMemoryManager 提供的 page 地址统一编码,由 TaskMemoryManager#encodePageNumberAndOffset(MemoryBlock page, long offsetInPage): long 实现

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
大数据IMF传奇行动绝密课程第51课:Spark性能优化第七季
Spark 体系架构
解决Spark OOM
Spark性能调优篇八之shuffle调优
Unsafe类操作java内存
spark内存管理器--MemoryManager源码解析
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服