科站网站,做网站卖东西,蛋糕网站内容规划,广州网站设计建设公司1. 内存的花费
1#xff09;每个Java对象#xff0c;都有一个对象头#xff0c;会占用16个字节#xff0c;主要是包括了一些对象的元信息#xff0c;比如指向它的类的指针。如果一个对象本身很小#xff0c;比如就包括了一个int类型的field#xff0c;那么它的对象头实…1. 内存的花费
1每个Java对象都有一个对象头会占用16个字节主要是包括了一些对象的元信息比如指向它的类的指针。如果一个对象本身很小比如就包括了一个int类型的field那么它的对象头实际上比对象自己还要大。
JAVA对象 对象头 实例数据 对象填充补余用的用于保证对象所占空间是8个字节的整数倍
2Java的String对象会比它内部的原始数据要多出40个字节。因为它内部使用char数组来保存内部的字符序列的并且还得保存诸如数组长度之类的信息。而且因为String使用的是UTF-16编码所以每个字符会占用2个字节。比如包含10个字符的String会占用60个字节。
3Java中的集合类型比如HashMap和LinkedList内部使用的是链表数据结构所以对链表中的每一个数据都使用了Entry对象来包装。Entry对象不仅有对象头还有指向下一个Entry的指针通常占用8个字节。
4元素类型为原始数据类型比如int的集合内部通常会使用原始数据类型的包装类型比如用Integer来存储元素。
下面将从 Spark 中内存管理的概述开始然后我们讨论可以采取的特定策略以更有效地使用内存。特别是我们将描述如何确定对象的内存使用情况以及如何改进它——通过更改数据结构或以序列化格式存储数据。然后我们将介绍调整 Spark 的缓存大小和 Java 垃圾收集器。
2. 内存管理
Spark的内存可以大体归为两类execution运行内存和storage存储内存前者包括shuffles、joins、sorts和aggregations所需内存后者包括cache和节点间数据传输所需内存
Spark1.6及以后引入的统一内存管理机制与静态内存管理的区别在于存储内存和执行内存共享同一块空间可以动态占用对方的空闲区域提供更好的性能。此种方式使得我们不需要修改内存比例。
3. 如何判断你的程序消耗了多少内存
这里有一个非常简单的办法来判断你的spark程序消耗了多少内存。
1首先自己设置RDD的并行度有下列方法
a) 在parallelize()、textFile()等方法中传入第二个参数设置RDD的task 或 partition的数量
b) 用SparkConf.set()方法设置一个参数spark.default.parallelism可以统一设置这个application所有RDD的partition数量。
2其次在程序中将RDD cache到内存中调用RDD.cache()方法即可。
3最后观察web ui val cacheRdd rdd.cache() //应该根据这个地方cache的结果进行内存的调节
// count行动算子触发运算。
cacheRdd.count()
4. 优化数据结构
减少内存消耗的第一种方法是避免Java语法特性中所导致的额外内存的开销比如基于指针的Java数据结构以及包装类型。
有一个关键的问题就是优化什么数据结构其实主要就是优化你的算子函数内部使用到的局部数据或者是算子函数外部的数据。都可以进行数据结构的优化。优化之后都会减少其对内存的消耗和占用。
优化方法
1能用数组取代就不用集合。比如用Array代替List。
2能用字符串取代就不用数组或集合。
3能用int型取代就不要用字符串比如Map的key可以用int取代字符串。
5. 对多次使用的RDD进行持久化或Checkpoint
RDD 持久化
如果程序中对某一个RDD基于它进行了多次transformation或者action操作。那么就非常有必要对其进行持久化操作以避免对一个RDD反复进行计算。
此外如果RDD的持久化数据可能会丢失的因为使用cache的时候还要保证高性能那么可以对RDD进行Checkpoint操作。
checkpoint:
checkpoint的意思就是建立检查点,类似于快照,当DAG计算过程出现问题了就可以从这个快照中恢复当然我们也可以通过cache或者persist将中间的计算结果放到内存或者磁盘中,但也未必完全可靠假如内存或者硬盘坏了也会导致spark从头再根据rdd计算一遍所以就有了checkpoint其中checkpoint的作用就是将DAG中比较重要的中间数据做一个检查点将结果存储到一个高可用的地方比如HDFS。
使用方法 6. 选择带有序列化的持久化级别
除了对多次使用的RDD进行持久化操作之外还可以进一步优化其性能。如果RDD数据持久化到内存或磁盘时如果内存不够就可能只缓存RDD的部分数据。
为了提高效率可以采取序列化持久到内存这样内存占用少。比如MEMORY_ONLY_SER、MEMORY_AND_DISK_SER等。 对于序列化的持久化级别还可以使用Kryo序列化进一步优化这样可以获得更快的序列化速度并且占用更小的内存空间。