Flink内存模型图

02内存模型 - 图1

JVM Heap

JVM Heap的划分

JVM ONHEAP

02内存模型 - 图2

  1. JVM内存划分为堆内存和非堆内存,堆内存分为年轻代(Young Generation)、老年代(Old Generation),非堆内存就一个永久代(Permanent Generation)。
  2. 年轻代又分为Eden和Survivor区。Survivor区由FromSpace和ToSpace组成。Eden区占大容量,Survivor两个区占小容量,默认比例是8:1:1。实际上是6:1:1

02内存模型 - 图3

  1. 堆内存用途:存放的是对象,垃圾收集器就是收集这些对象,然后根据GC算法回收。
  2. 非堆内存用途:永久代,也称为方法区,存储程序运行时长期存活的对象,比如类的元数据、方法、常量、属性等。

JVM OFFHEAP

  1. **堆外内存**就是把内存对象分配在Java虚拟机的堆以外的内存,这些内存直接**受操作系统管理**(而不是虚拟机),这样做的结果就是**能够在一定程度上减少垃圾回收对应用程序造成的影响。**
  2. 堆外内存存放:所有线程共享的方法区,方法区中包含类结构、常数池、字段和方法数据,以及方法和构造方法的代码

Flink FrameworkHeap 存放了什么?

  1. 存放了Flink框架所需要用到的对象

Task Heap 存放了什么?

  1. 存放了Task中创建的对象

Off-Heap Memory

堆外内存的好处与劣势

  1. 好处:jvm虚拟化大量heap内存耗时较久,使用堆外内存的话可以有效的避免该环节
  2. 坏处:监控调试使用相对复杂,对于生命周期较短的segment使用堆内内存开销更低,flink在一些情况下,直接操作二进制数据,避免一些反序列化带来的开销。如果需要处理的数据超出了内存限制,则会将部分数据存储到硬盘上。

02内存模型 - 图4

Managed Memory

存储:

  1. RocksDBStateBackend
  2. 批处理算子,排序、哈希表、缓存中间结果
  3. 属于native memory的范畴

RocksDBStateBackend:

  1. Rocksdbrocksdb基于lsm数据结构实现,每个state对应一个列族。
  2. 占有独立的writebufferrocksdb占用native内存大小为 blockCahe + writebufferNum * writeBuffer + index
  3. 同时堆外内存是进程之间共享的

Direct Memory 直接内存

什么是直接内存?

  1. 直接内存实质上是堆外内存native memory通过存储在堆内的**DirectByteBuffer**操作native memory

什么时候使用直接内存?

  1. 如果读写频繁的操作可以使用直接内存,直接内存的速度会优于java堆,可以使用java Nio库,用于数据缓冲

图解直接缓冲区

非直接缓冲区:

02内存模型 - 图5

直接缓冲区:

02内存模型 - 图6

应用程序直接内核态访问,节省copy

存在的隐患

  1. OOM,直接内存+JVM堆内存会受操作系统的限制
  2. 分配回收成本较高,不受JVM内存回收管理
分配
  • 直接内存大小可以通过MaxDirectMemorySize设置
  • 如果不指定,默认与堆的最大值一Xmx参数值一致

Network

  1. 关于Network对堆外内存的使用可以查看反压机制

反压