[spark]如何优化数据结构

本文介绍在Spark大数据处理中,如何通过优化数据结构减少内存消耗,提高处理效率。具体包括使用数组代替集合、避免多层嵌套对象及用int替代String等方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

导读(为什么要优化?):


在spark开发中,如果数据量很大的情况下(亿级),即使是基于内存的spark也会吃不消,很可能会发生意想不到的一些异常(堆栈溢出、OOM内存溢出等),

这时,如何优化使得我们的程序性能更加的好,速度更加的快就是第一任务了,以下是针对数据结构的一些优化解决方案供大家参考



数据结构耗费内存情况:


1、每个Java对象,都有一个对象头,会占用16个字节,主要是包括了一些对象的元信息,比如指向它的类的指针,如果一个对象本身很小,比如就包括了一个int类型的field,那么它的对象头实际上比对象自己还要大。


2、java的String对象,会比它内部的原始数据,多出40个字节,因为它内部使用的char数组来保存内部的字符序列,并且还得保存诸如数组长度之类的信息,且String使用的是UTF-16编码,所以每个字符会占用2个字节,比如,包含10个字符的String,会占用60个字节。


3、java中的集合类型,比如HashMap和LinkedList,内部使用的是链表数据结构,所以对链表中的每一个数据,都使用了Entry对象来包装,Entry对象不光有对象头,还有指向下一个Entry的指针,通常占用8个字节。


4、元素类型为原始数据类型(比如int)的集合,内部通常会使用原始数据类型的包装类型,比如Integer,来存储元素.




适用场景:


算子函数内部的局部数据,或者是算子函数外部的数据,均可参考以下数据结构的优化方案。


方案(一)


1.优先使用数组以及字符串,能不用集合类的,就不用集合类(优先使用array,而不是ArrayList、LinkedList、HashMap等集合)


示例:


比如有一个List<Integer> list = new ArrayList<Integer>(),将其替换为int[] arr = new int[]

或者说,对于HashMap、List这种数据,统一用String拼接成特殊格式的字符串,比如Map<Integer,Person> person = new HashMap<Integer,Person>()

可以优化为,特殊的字符串格式: id:name.address|id:name,address...

作用:


array既比List少了额外信息的存储开销,还能使用原始数据类型(int)来存储数据,比List中用Integer这种包装类型存储数据,要节省内存的多


方案(二)


2.应避免使用多层嵌套的对象结构,比如说;public class Teacher{private list<Student> students = new ArrayList<Student>()},这就是一个非常不好的例子,因为Teacher类的内部又嵌套了大量的小student对象


对于上述情况,也可以完全使用特殊的字符串来进行数据的存储,比如,用json字符串来存储数据,就是一个很好的选择。


示例:


{"teacherld:"1,"teacherName":"leo",students:[{"student":1,"studentName":"tom"}]}


作用:


作用同方案一


方案(三)


3.对于有些能够避免的场景:


尽量使用int替代String,因为String虽然比ArrayList、HashMap等数据结构高效、占用内存少、但是String还是有额外信息的消耗,比如之前用String表示id,那么现在完全可以用数字类型的int,来进行替代(注:id不要用常用的uuid,因为无法转成int,就用自增类型的int类型的id即可)




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值