1、堆外内存
| 堆外直接内存(DirectByteBuffer) | 堆外不安全内存(Unsafe) | |
|---|---|---|
| 管理方式 | JVM 通过 Cleaner 机制自动回收 | 手动管理 |
| 分配入口 | ByteBuffer.allocateDirect() | Unsafe.allocateMemory() |
| 内存释放 | GC 回收关联的 DirectByteBuffer 时触发 | 显式调用 Unsafe.freeMemory() |
| 使用场景 | NIO 网络/文件传输、大型缓存 | 高频实时计算、自定义数据结构 |
| e.g. | DirectByteBuffer,Netty 的 ByteBuf 底层实现,Kafka 的文件页缓存(Page Cache)。 | Unsafejava.util.concurrent.atomic 包的 CAS 操作,Spark 的 Tungsten 引擎(堆外数据存储)。Java 9+,部分 Unsafe 功能被标准化为 VarHandle 和 MemorySegment |
2、Flink内存
1、核心组件
1、MemorySegment
统一管理堆内/堆外内存;内存可以是堆上内存、堆外直接内存或堆外不安全内存;Flink 内存管理的基本单元。代表一段固定大小的连续内存(taskmanager.memory.segment-size 默认32KB)
- 堆内内存 :(
byte[]) - 堆外直接内存 : 堆外内存 (
java.nio.ByteBuffer分配的 Direct Memory)。序列化/反序列化、网络传输、RocksDB 状态后端 - 堆外不安全内存: 更高层数据结构(如
DataInputView/DataOutputView,Record缓冲区)的基础
2、MemoryManager
管理任务托管内存(排序、哈希表、缓存等)
3、ShuffleEnvironment
- 生产者端:
- ResultPartition 从 LocalBufferPool 获取 Buffer
- 序列化数据 → 写入 Buffer → 通过 Netty 发送
- 消费者端:
- InputGate 接收网络数据
- 将 Buffer 存入关联的 LocalBufferPool
- Task 线程从池中读取数据处理
4、TaskSlotTable
- 槽位创建时绑定固定内存配额
- 执行任务时向MemoryManager申请预留内存
- 每个Slot独立内存空间
5、LocalBufferPool
单个任务网络缓冲区的本地管理
6、NetworkBufferPool
TaskManager 级别的全局内存池,统一管理所有网络传输内存。
创建 → 分配给LocalBufferPool → 传输数据 → 回收 → 重回池中
7、执行流程
- TaskManager 启动时初始化 NetworkBufferPool
- TaskSlotTable 创建 Slot 并绑定 MemoryManager
- 任务部署时:
- 向 TaskSlotTable 申请 Slot
- MemoryManager 分配托管内存
- ShuffleEnvironment 创建 LocalBufferPool
- 任务运行时:
- 生产者/消费者通过 LocalBufferPool 申请缓冲区
- 网络传输使用 NetworkBufferPool 的物理内存
- 任务结束时:
- 释放 LocalBufferPool 到 NetworkBufferPool
- 回收 MemoryManager 托管内存
- TaskSlotTable 释放 Slot
2、Flink内部布局
1、JobManager
JobManagerProcessSpec
┌ ─ ─ Total Process Memory ─ ─ ┐
┌ ─ ─ Total Flink Memory ─ ─ ┐
│ ┌───────────────────────────┐ │
On-Heap ----- ││ JVM Heap Memory ││
│ └───────────────────────────┘ │
│ ┌───────────────────────────┐ │
┌─ ││ Off-heap Memory ││
│ │ └───────────────────────────┘ │
│ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
│ │┌─────────────────────────────┐│
Off-Heap ─| │ JVM Metaspace │
│ │└─────────────────────────────┘│
│ ┌─────────────────────────────┐
└─ ││ JVM Overhead ││
└─────────────────────────────┘
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
- JVM Heap : 用于 Flink 框架自身、用户代码,Checkpoint 、Job Cache等。
- Off-Heap Memory : JM 网络通信(Akka)、可能是 JM 外部的 Flink 框架依赖(目前来看,要么没有,要么可以忽略)、在某些情况下,用户代码在提交作业期间运行,或者在检查点完成回调中运行
- JVM Metaspace : 类元数据空间。
- JVM Overhead : 为 JVM 自身预留的内存(线程栈、代码缓存、GC 数据结构等)。
2、TaskExecutor
TaskExecutorProcessSpec
┌ ─ ─ Total Process Memory ─ ─ ┐
┌ ─ ─ Total Flink Memory ─ ─ ┐
│ ┌───────────────────────────┐ │
││ Framework Heap Memory ││ ─┐
│ └───────────────────────────┘ │ │
│ ┌───────────────────────────┐ │ │
┌─ ││ Framework Off-Heap Memory ││ ├─ On-Heap
│ │ └───────────────────────────┘ │ │
│ │┌───────────────────────────┐│ │
│ │ │ Task Heap Memory │ │ ─┘
│ │└───────────────────────────┘│
│ │ ┌───────────────────────────┐ │
├─ ││ Task Off-Heap Memory ││
│ │ └───────────────────────────┘ │
│ │┌───────────────────────────┐│
├─ │ │ Network Memory │ │
│ │└───────────────────────────┘│
│ │ ┌───────────────────────────┐ │
Off-Heap ─┼─ │ Managed Memory │
│ ││└───────────────────────────┘││
│ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
│ │┌─────────────────────────────┐│
├─ │ JVM Metaspace │
│ │└─────────────────────────────┘│
│ ┌─────────────────────────────┐
└─ ││ JVM Overhead ││
└─────────────────────────────┘
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
- JVM Heap : 主要留给用户代码(UDF)使用
- Managed Memory : 由 Flink 托管的堆外内存,用于 RocksDB 状态后端、批处理算法(排序、Hash Join)、PyFlink 等。
- Framework Heap/Off-Heap Memory : Flink 框架自身运行时需要的内存(较小且通常固定),它不计入 slot 资源配置(默认 128mb)。
- Network Memory : 至关重要,用于
NetworkBufferPool分配MemorySegment给网络传输。 - Task Off-Heap Memory : 直接分配给用户任务的堆外内存。
- JVM Metaspace : 类元数据空间。
- JVM Overhead : 为 JVM 自身预留的内存(线程栈、代码缓存、GC 数据结构等)。
1002

被折叠的 条评论
为什么被折叠?



