垃圾回收器(Garbage Collect GC):寻找内存中哪些对象已不再使用,然后就清理掉这些对象,腾出空间用于创建其它新对象。

GC的影响:

1.GC对性能的影响在于,如果内存中数据量比较大时,会频繁造成内存空间不足,此时gc频繁发生,而gc发生是有性能消耗的。

2.如果要回收的数据量特别大,gc的过程也会比较慢

3.gc过程中会让task工作线程停止,让gc线程独立运行,这就直接导致了task执行的停止,从而降低了spark的性能。

所以,频繁发生gc会使spark性能大幅下降,可通过worker日志文件或4040UI界面进行GC的监控。

----------------------------------------

Executor的内存主要用于两个方面:

1.用于缓存RDD  (cache操作);

2.分配给task,在task执行过程中创建对象。

默认情况下,Executor的内存有60%划分给了RDD缓存,40%分配给task,存放运行期间创建的对象。这种默认情况可能会导致task用于运行期间创建对象的内存偏小了。当创建的对象把40%的内存空间用完,就会产生垃圾回收(GC),把不再被使用的对象清除出内存。所以说,如果给task分配的内存过低,会导致GC频繁发生,从而导致task工作线程频繁停止,降低了spark计算效率。

优化方法:SparkConf().set("spark.storage.memoryFraction","比例"),此处的比例为RDD缓存的内存分配比例,rdd的持久化也可通过序列化来降低内存的占用。

--------------------------------------------------

分配给task的内存细化

分配给task的内存空间被划分成了两块:

1.老年代(存放长时间存活的对象)

2.新生代(存放短时间存活的对象)

新生代接着被划分为三块区域:

1.Eden

2.Survivor1

3.Survivor2

新创建的对象都是被存放在Eden和Survivor1区域,Survivor2作为备用。Eden区域满了之后,就会触发Mirror gc(小垃圾回收),会回收新生代中不再被使用的对象,此时Eden和Survivor1中仍存活的对象被移入到Survivor2中。移动完之后,Survivor1和Survivor2角色互换,如此反复。

如果一个对象在对此的Mirror gc中存活下来,则将其移入老年代。在特殊情况下,如果备用Survivor满了,则在Mirro gc后将新的存活对象直接移入到老年代,所以老年代仍有可能有存活时间较短的对象,当老年代也满了会触发full gc操作,回收老年代的对象,full gc会消耗大量资源。