当前位置:首页 > 内存 > 正文

堆外内存(ehcache使用堆外内存)

  • 内存
  • 2024-07-01 23:42:11
  • 6846

一、SparkonYarn为什么出现内存超界container被kill一个执行器对应一个JVM进程。从Spark的角度来看,Executor占用的内存分为两部分:ExecutorMemory和MemoryOverhead。其中,ExecutorMemory是JVM进程的Java堆区域,MemoryOverhead是JVM进程除了Java堆之外所占用的空间,包括方法区(永久代)、Java虚拟机栈、本地方法栈、JVM进程本身使用的内存和堆(DirectMemory)等。
和分别设置Spark的Driver和Executor的ExecutorMemory。
Overhead和Overhead分别设置Driver和Executor的MemoryOverhead。
此外,Spark会在MaxDirectMemorySize堆外分配大量内存,通过javaOptions配置最大值。
堆外内存的最大大小可以与ExecutorMemory相同,但是堆外内存的大小受到MemoryOverhead的限制,因此当MaxDirectMemorySize、ExecutorMemory和MemoryOverhead设置不合理时。容器的内存可能会超出限制并被线程杀死。
例如“ExecutorMemory”为8G,“MemoryOverhead”为4G,未设置“MaxDirectMemorySize”。为8G,导致容器最多可以使用16G以上。
合理的放置规则为:ExecutorMemory+MemoryOverhead>ExecutorMemory+MaxDirectMemorySize
因此Spark应用占用的池内存总大小为:
参数调优建议:
将每个执行器进程的内存设置为4G~8G比较方便。
将每个执行器的CPU核数设置为2到4个比较方便。
以下是一些推荐的参数设置:


二、Spark原理|内存管理Spark作为一个基于内存的分布式计算引擎,其内存管理模块在整个系统中扮演着非常重要的角色。
执行Spark应用时,Spark集群会启动两个JVM进程,Driver和Executor:
Spark管理的内存主要分为4个区域:
Executor作为一个JVM进程,其内存管理是基于JVM的内存管理的。Spark更详细地分配JVM的堆上空间,以充分利用内存。同时,Spark引入了堆外内存,可以直接在工作节点的系统内存中开辟空间,进一步优化内存的使用。
堆中内存的大小是在Spark应用程序启动时通过executor-memory或参数配置的。Executor中运行的并发任务共享JVM堆内存。这些任务在缓存RDD数据和广播数据时占用的内存被规划为存储内存,这些任务在执行Shuffle时占用的内存被规划为执行(Execution)内存,剩下的部分没有特别规划,里面的那些对象实例Spark,或者用户定义的Spark应用程序中的对象实例,都占用剩余空间。在不同的管理模式下,这三个部分占据的空间大小不同。
Spark对堆内内存的管理是一种逻辑上的“规划”管理,因为对象实例占用的内存的申请和释放都是由JVM完成的,Spark只能申请后才能申请和释放。之前记录了这些内存,我们看一下具体的过程:
为了进一步优化内存的使用,提高Shuffle时排序的效率,Spark引入了堆外内存,这样可以可以直接在worker节点的系统内存中创建空间来存储序列化的二进制数据。使用JDKUnsafeAPI(从Spark2.0开始),堆外的存储内存不再基于Tachyon,而是与堆外的执行内存相同。基于JDKUnsafeAPI实现,Spark可以直接操作堆外内存,减少不必要的Memory开销,以及频繁的GC扫描和回收,提高处理性能。堆外内存可以精确申请和释放,并且可以精确计算序列化数据占用的空间,因此与堆内内存相比,降低了管理难度,减少了错误。
默认情况下不启用堆外内存。可以通过配置d参数来启用,堆外空间的大小由参数设置。除了没有其他空间外,堆外内存的划分方式与堆内内存相同。所有正在运行的并发任务共享存储内存和执行内存。
Spark1.6之后,默认是统一管理(UnifiedMemoryManager)方式。1.6之前使用的静态管理(StaticMemoryManager)方法仍然保留。可以通过配置acyMode=true参数来启用静态内存管理。方式。下面我们介绍一下两种内存管理模型的演变。
在Spark最初采用的静态内存管理机制下,存储内存、执行内存等内存的大小在Spark应用程序运行过程中是固定的,但用户可以在应用程序启动前进行配置。堆中内存的分配如下:
Spark1.6之后引入的统一内存管理机制,与静态内存管理不同的是,存储内存和执行内存共享相同的空间,可以动态占用对方的空间。空间。自由区。如下图:
最重要的优化是动态占用机制,规则如下:
新版本引入了新的配置项:
Spark凭借其统一的内存管理机制,在一定程度上提高了堆内和堆外内存资源的利用率,降低了开发者维护Spark内存的难度,但这并不意味着开发者就可以坐以待毙回来放松一下。例如,如果存储内存空间太大或者缓存数据太多,就会导致频繁的全量垃圾回收,降低任务执行的性能,因为缓存的RDD数据通常会长时间驻留在内存中。因此,为了充分发挥Spark的性能,开发人员需要进一步了解存储内存和执行内存的管理方法和实现原理。

上一篇:堆外内存监控

下一篇:堆外内存不足