1.spark程序耗费内存主要是堆内还是堆外?

先给你最直接结论:
Spark 程序绝大部分内存消耗在堆内(On-heap),堆外(Off-heap)只是辅助、可选项,默认不开启、也不占主要。
1. 一句话总结

• 默认情况下:几乎 100% 是堆内内存

• 堆外内存默认关闭,只有你显式配置 spark.memory.offHeap.enabled=true 才会启用

• 即使开了堆外,业务数据、缓存、执行内存依然主要在堆内
2. 为什么主要是堆内?

Spark 把 Executor 内存分成三大块:

1. Execution 内存:shuffle、join、sort、agg 等计算用

2. Storage 内存:cache、persist 缓存 RDD/DataFrame

3. User 代码 / 预留内存

这三块默认全在 JVM 堆内,由 JVM 管理。
3. 堆外内存用来干嘛?

开了堆外后,主要只用在:

• 部分 shuffle 数据读写

• 部分 网络传输缓冲

• 某些 列式缓存/unsafe 操作

它的作用是:

• 减少 GC 压力

• 避免堆内 OOM

• 提升大集群、大 shuffle 稳定性

但它永远不是你程序内存消耗的大头。
4. 你线上遇到内存问题,优先看哪里?

99% 情况都是:

1. Executor 堆内存太小

2. 并行度太高,task 太多

3. 数据倾斜,某个 task 爆内存

4. cache/persist 占太多 Storage 内存

不是堆外的锅。
5. 极简配置记忆

• 堆内大小:spark.executor.memory

• 堆外大小:spark.memory.offHeap.size(默认 0)

• 堆外开关:spark.memory.offHeap.enabled(默认 false)
如果你愿意,我可以按你实际集群配置 + 业务场景,帮你算一套最优的 Spark 内存+并行度调优参数。

更多推荐