【Flink】Flink内存调优

Flink内存调优

JVM

我们知道Flink是基于JobManager和TaskManager管理和运行任务,而他们都是以Java进程的形式运行的,所以在了解 Flink 内存时,我们需要先了解一下Java运行时环境Java虚拟机(JVM) 。

JVM 是可运行 Java 代码的假想计算机 ,包括程序计数器、Java 虚拟机栈、本地方法栈、Java 堆 和方法区。JVM 是运行在操作系统之上的,它与硬件没有直接的交互。

JVM 数据运行区

在这里插入图片描述
Java 虚拟机在执行 Java 程序的过程中会把它在主存中管理的内存部分划分成多个区域,每个区域存放不同类型的数据。

  1. 程序计数器:是一个数据结构,用于保存当前正常执行的程序的内存地址。
  2. JVM虚拟机栈:与线程生命周期相同,用于存储局部变量表,操作栈,方法返回值。
  3. 本地方法栈**:**跟虚拟机栈很像,不过它是为虚拟机使用到的 Native 方法服务。
  4. 方法区(元空间):储存虚拟机加载的类信息,常量,静态变量,编译后的代码。
  5. JVM 堆:存放所有对象的实例。

堆外内存(off-heap memory)

虽然 Java 提供了多种算法进行垃圾回收,但仍然无法彻底解决堆内内存过大带来的长时间的 GC 停顿的问题,以及操作系统对堆内内存不可知的问题。

基于上述问题,Java 虚拟机开辟出了堆外内存(off-heap memory)。堆外内存意味着把一些对象的实例分配在 Java 虚拟机堆内内存以外的内存区域,这些内存直接受操作系统(而不是虚拟机)管理。这样做的结果就是能保持一个较小的堆,以减少垃圾收集对应用的影响。同时因为这部分区域直接受操作系统的管理,别的进程和设备(例如 GPU )可以直接通过操作系统对其进行访问,减少了从虚拟机中复制内存数据的过程。

堆外内存与堆内内存联系

虽然堆外内存本身不受垃圾回收算法的管辖,但是因为其是由 ByteBuffer 所创造出来的,因此这个 buffer 自身作为一个实例化的对象,其自身的信息(例如堆外内存在主存中的起始地址等信息)必须存储在堆内内存中。

JVM 内存管理缺陷

由于在 JVM 内存中存储大量的数据 (包括缓存和高效处理)时,JVM 内存会面临很多问题,包括如下:

  1. Java 对象存储**密度低。**Java 的对象在内存中存储包含 3 个主要部分:对象头、实例 数据、对齐填充部分。例如,一个只包含 boolean 属性的对象占 16byte:对象头占 8byte, boolean 属性占 1byte,为了对齐达到 8 的倍数额外占 7byte。而实际上只需要一个 bit(1/8 字节)就够了。
  2. **Full GC 会极大地影响性能。**尤其是为了处理更大数据而开了很大内存空间的 JVM 来说,GC 会达到秒级甚至分钟级。
  3. **OOM 问题影响稳定性。**OutOfMemoryError 是分布式计算框架经常会遇到的问题, 当 JVM 中所有对象大小超过分配给 JVM 的内存大小时,就会发生 OutOfMemoryError 错误, 导致 JVM 崩溃,分布式框架的健壮性和性能都会受到影响。
  4. **缓存未命中问题。**CPU 进行计算的时候,是从 CPU 缓存中获取数据。现代体系的 CPU 会有多级缓存,而加载的时候是以 Cache Line 为单位加载。如果能够将对象连续存储, 这样就会大大降低 Cache Miss。使得 CPU 集中处理业务,而不是空转。

Flink内存模型

Flink内部封装了一套自己的内存组件,MemorySegment内存分片是最小的内存单位,Flink通过实现DataInputView接口来更好的控制MemorySegment

MemorySegment

内存分片,控制内存的单位,以下是它的属性:

this.heapMemory = buffer;
this.offHeapBuffer = null;
this.size = buffer.length;
this.address = BYTE_ARRAY_BASE_OFFSET;
this.addressLimit = this.address + this.size;
this.owner = owner;
this.allowWrap = true;
this.cleaner = null;
this.isFreedAtomic = new AtomicBoolean(false);

DataInputView

DataInputView继承DataInput接口

DataInput

void readFully(byte b[]) throws IOException;
void readFully(byte b[], int off, int len) throws IOException;
boolean readBoolean() throws IOException;
byte readByte() throws IOException;
int readUnsignedByte() throws IOException;
short readShort() throws IOException;
int readUnsignedShort() throws IOException;
char readChar() throws IOException;
int readInt() throws IOException;
long readLong() throws IOException
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值