我在这里读到了很多关于数据帧上的unssist()的问题和答案。到目前为止,我还没有找到这个问题的答案:
在Spark中,一旦我完成了一个数据帧,那么调用.uninsist()手动强制从内存中取消该数据帧,而不是等待GC(这是一项昂贵的任务),这是一个好主意吗在我的情况下,我正在加载许多数据帧,以便执行联接和其他转换。
因此,例如,如果我希望加载并连接3个数据帧A、B和C:我加载数据帧A和B,将这两个连接起来创建X,然后是.uninsist()B,因为我不再需要它了(但我需要A),并且可以使用内存加载C(很大)。因此,我加载C,并将C连接到X,在C上执行.uninsist(),这样我就有了更多的内存来执行现在将在X和A上执行的操作。
我知道GC最终会对我不抗拒,但我也明白GC是一项昂贵的任务,如果可能的话应该避免。重新表述我的问题:这是一种手动管理内存的合适方法吗?
我的理解(如有错误,请更正):
- 我知道.unssist()是一个非常便宜的操作
- 我知道GC最终会在我的数据帧上调用.uninsist()
- 我知道spark根据最近使用的策略来监控缓存和丢弃。但在某些情况下,我不希望删除"Last Used"DF,因此我可以对我知道我将来不会需要的数据文件调用.unssist(),这样我就不会删除我将需要的DF,并且以后必须重新加载它们
如果我的问题不清楚,请再次重申:这是.unssist()的适当使用吗?还是我应该让Spark和GC完成他们的工作?
提前感谢:)
似乎有一些误解。虽然使用unpersist
是更好地控制存储的有效方法,但它并不能避免垃圾收集。事实上,所有与缓存数据相关联的堆上对象都将保留为垃圾收集器。
因此,虽然操作本身相对便宜,但它引发的一连串事件可能并不便宜。幸运的是,显式持久化并不比等待自动清理器或GC触发的清理器更糟糕,所以如果你想清理特定的对象,就去做吧
为了将GC限制在unconsist上,可能值得一看OFF_HEAP
StorageLevel
。