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