我正在研究spark,我对执行者的记忆分裂有些怀疑。具体而言,spark apache文档(此处)中指出:
java堆空间分为两个区域:年轻的和老的。年轻一代是用来存放寿命较短的物品,而老一代则是用来存放寿命较长的物品。
这个:
但是对于spark executor,内存还有另一个抽象划分,如spark apache doc所述(在这里):
spark中的内存使用主要分为两类:执行和存储。执行内存指的是用于无序、联接、排序和聚合的计算,而存储内存指的是用于缓存和跨集群传播内部数据的内存。在spark中,执行和存储共享一个统一的区域(m)。
如图所示:
我不明白young gen\old gen与storage\execution memory有多重叠,因为在同一个doc(总是在这里)中指出:
fraction将m的大小表示为(jvm堆空间-300mib)的一部分(默认值为0.6)。其余的空间(40%)用于用户数据结构、spark中的内部元数据,以及在稀疏和异常大的记录情况下防止oom错误。
哪里 spark.memory.fraction
表示java堆的执行\存储内存部分
但是
如果oldgen快满了,通过降低spark.memory.fraction来减少用于缓存的内存量;缓存较少的对象比减慢任务执行速度要好。
这似乎表明oldgen实际上是用户内存,但下面的语句似乎与我的假设相矛盾
如果老年人快要吃饱了,或者,考虑缩小年轻一代的规模。
我看不到什么?
年轻一代\老一代的分裂与星火分数\用户内存有什么关系?
1条答案
按热度按时间mpbci0fu1#
简而言之,除了两者都与jvm堆有关外,它们之间并没有真正的联系。
更好的方法是有四个桶(编号顺序不重要):
激发年轻一代的记忆
旧时代的Spark记忆
年轻一代的用户记忆
旧一代中的用户内存
(从技术上讲,也有一些系统内存既不是spark也不是user,但它通常足够小,不必担心:它也可以是旧的或年轻的)。
一个对象被归类为spark还是user是由spark决定的(实际上我不知道这是一个永恒的名称,还是对象可以在这方面改变它们的分类)。
至于old和young,这是由垃圾收集器和gc can管理的,它将把对象从young升级到old。在一些gc算法中,生成的大小是动态调整的(或者它们使用固定大小的区域,并且给定的区域可以是旧的或年轻的)。
您可以控制1+2、3+4、1+3和2+4的总容量,但实际上您并没有控制1、2、3或4的容量(而且可能不是真的想要,因为能够在一个类别中使用多余的空间比在另一个类别中临时获得更多的空间有很多好处)。