堆内内存的大小,由 Spark 应用程序启动时的 –executor-memory 或 spark.executor.memory 参数配置。Executor 内运行的并发任务共享 JVM 堆内内存,这些任务在缓存 RDD 数据和广播(Broadcast)数据时占用的内存被规划为存储(Storage)内存,而这些任务在执行 Shuffle 时占用的内存被规划为执行(Execution)内存,剩余的部分不作特殊规划,那些 Spark 内部的对象实例,或者用户定义的 Spark 应用程序中的对象实例,均占用剩余的空间。不一样的管理模式下,这三部分占用的空间大小各不相同。缓存
在默认状况下堆外内存并不启用,可经过配置 spark.memory.offHeap.enabled 参数启用,并由 spark.memory.offHeap.size 参数设定堆外空间的大小。除了没有 other 空间,堆外内存与堆内内存的划分方式相同,全部运行中的并发任务共享存储内存和执行内存。并发
Spark 1.6 以后引入的统一内存管理机制,与静态内存管理的区别在于存储内存和执行内存共享同一块空间,能够动态占用对方的空闲区域,如图 4 和图 5 所示性能
图 4 . 统一内存管理图示——堆内优化
spark.memory.fraction 堆内的存储内存和执行内存总共所占的比例,默认0.6spa
spark.storage.storageFraction 用于缓存数据的内存比例,默认0.5对象
图 5 . 统一内存管理图示——堆外blog
spark.memory.storageFraction Storage内存所占堆外内存的比例,默认为0.5内存
其中最重要的优化在于动态占用机制,其规则以下:资源
图 6 . 动态占用机制图示开发
凭借统一内存管理机制,Spark 在必定程度上提升了堆内和堆外内存资源的利用率,下降了开发者维护 Spark 内存的难度,但并不意味着开发者能够高枕无忧。譬如,因此若是存储内存的空间太大或者说缓存的数据过多,反而会致使频繁的全量垃圾回收,下降任务执行时的性能,由于缓存的 RDD 数据一般都是长期驻留内存的 。因此要想充分发挥 Spark 的性能,须要开发者进一步了解存储内存和执行内存各自的管理方式和实现原理。