根据这篇帖子How long does RDD remain in memory?,基于以下几点,我想知道:
RDD是一个与其他对象一样的对象。如果您不坚持/缓存 它将充当托管语言下的任何其他对象,并且 一旦没有活着的根对象指向它,该被收集吗?
一旦没有活动的根对象指向它,到底是什么意思??
我读了尽可能多的书,但发现我脑子里总有一个未解决的问题。这位知名专家的回应让我心存疑虑,我无法驱逐。
When does a RDD lineage is created? How to find lineage graph?示例很好,在此处重新显示:
val nums = sc.parallelize(0 to 9)
scala> nums.toDebugString
res0: String = (8) ParallelCollectionRDD[0] at parallelize at <console>:24 []
val doubles = nums.map(_ * 2)
scala> doubles.toDebugString
res1: String =
(8) MapPartitionsRDD[1] at map at <console>:25 []
| ParallelCollectionRDD[0] at parallelize at <console>:24 []
val groups = doubles.groupBy(_ < 10)
scala> groups.toDebugString
res2: String =
(8) ShuffledRDD[3] at groupBy at <console>:25 []
+-(8) MapPartitionsRDD[2] at groupBy at <console>:25 []
| MapPartitionsRDD[1] at map at <console>:25 []
| ParallelCollectionRDD[0] at parallelize at <console>:24 []
假设每个转换都需要很长时间才能实际执行,那么何时可以驱除RDD [0]?即最早的时间点。关键是... RDD [0]是... RDD [1..N]的父对象还是所有此类对象的父对象?我在其他地方找到这样的声明时说。
我不认为它是重复的,它正在寻求澄清所陈述的内容。
我的解释是,术语“根对象”意味着RDD [0]不能进行垃圾回收,直到发生某个Action或Action DAG路径中的缓存或检查点发生为止。寻求验证。对于我来说关于根对象是什么的句子现在还不清楚。我本以为根对象是链中较早的RDD。
答案 0 :(得分:4)
RDD具有不同类型的内存足迹:
1)它消耗驱动程序上的内存(作为常规对象)
2)有关该RDD的信息已分配给工作人员
3)如果缓存了RDD,它可能会在worker上分配额外的空间
当根据(1)无法访问RDD时,将通过ContextCleaner
触发对(2)和(3)的清除。
所以我们只在谈论(1)。
RDD是否已缓存完全无关紧要。执行count
/ collect
之类的动作也没有关系。
当您离开该RDD可见的范围时,RDD只是作为常规的Java对象而消失。
在您的特定示例中,RDD1
取决于RDD0
,因此除非前者被驱逐,否则后者将不会被驱逐。并且RDD1
仅在RDD2
之后被驱逐,而RDD3
之后将被驱逐。要为垃圾收集器解锁RDD3
,您必须(隐约地说)将方法保留在使用它的位置。