首页 > 解决方案 > Spark内存分数与年轻一代/老一代java堆拆分

问题描述

我正在研究 Spark,我对 Executor 内存拆分有一些疑问。具体来说,在 Spark Apache 文档(此处)中指出:

Java 堆空间分为两个区域 Young 和 Old。新生代用于保存寿命较短的对象,而老年代用于保存寿命较长的对象。

这个:

在此处输入图像描述

但是对于 Spark Executor,内存还有另一个抽象拆分,如 spark apache doc(此处)所述:

Spark 中的内存使用主要属于以下两类之一:执行和存储。执行内存是指用于混洗、连接、排序和聚合中的计算,而存储内存是指用于在集群中缓存和传播内部数据的内存。在 Spark 中,执行和存储共享一个统一的区域 (M)。

如此处所示:

在此处输入图像描述

我不明白 Young Gen\Old gen 如何与存储\执行内存重叠,因为在同一个文档(总是在这里)中声明:

spark.memory.fraction 将 M 的大小表示为(JVM 堆空间 - 300MiB)的一部分(默认为 0.6)。其余空间 (40%) 保留用于用户数据结构、Spark 中的内部元数据,以及在记录稀疏和异常大的情况下防止 OOM 错误。

其中spark.memory.fraction代表 Java Heap 的执行\存储内存部分

如果 OldGen 快满了,通过降低 spark.memory.fraction 来减少用于缓存的内存量;缓存更少的对象比减慢任务执行速度要好。

这似乎表明 oldgen 实际上是 User Memory,但以下陈述似乎与我的假设相矛盾

如果 OldGen 快满了,或者考虑减小年轻代的大小。

我没看到什么?

Young Gen\Old Gen 分裂与 spark 分数 \ User Memory 有什么关系?

标签: javascalaapache-sparkheap-memory

解决方案


简短的回答是,除了与 JVM 堆有关之外,它们并没有真正的关系。

考虑这一点的更好方法是有四个桶(编号不重要):

  1. 激发年轻一代的记忆
  2. 老一代的火花记忆
  3. 年轻一代的用户记忆
  4. 老一代的用户内存

(从技术上讲,还有一些既不是 Spark 也不是 User 的系统内存,但这通常足够小而不必担心:这也可能是旧的或年轻的)。

一个对象是归类为 Spark 还是 User 是由 Spark 决定的(我实际上不知道这是否是一个永恒的名称,或者对象是否可以在这方面改变它们的分类)。

至于old vs.young,这是由垃圾收集器管理的,GC可以并且将把对象从young提升到old。在一些 GC 算法中,世代的大小是动态调整的(或者它们使用固定大小的区域,并且给定的区域可以是老的或年轻的)。

您可以控制 1+2、3+4、1+3 和 2+4 的总容量,但您实际上并没有(并且可能并不真正想要,因为能够控制有很多好处)在一个类别中使用多余的空间来暂时在另一个类别中获得更多空间)控制 1、2、3 或 4 的容量。


推荐阅读