優(yōu)化數(shù)據(jù)結(jié)構(gòu)
要減少內(nèi)存的消耗,除了使用高效的序列化類庫以外硫痰,還有一個(gè)很重要的事情,就是優(yōu)化數(shù)據(jù)結(jié)構(gòu)窜护。從而避免Java語法特性中所導(dǎo)致的額外內(nèi)存的開銷效斑,比如基于指針的Java數(shù)據(jù)結(jié)構(gòu),以及包裝類型柱徙。
有一個(gè)關(guān)鍵的問題缓屠,就是優(yōu)化什么數(shù)據(jù)結(jié)構(gòu)?其實(shí)主要就是優(yōu)化你的算子函數(shù)护侮,內(nèi)部使用到的局部數(shù)據(jù)敌完,或者是算子函數(shù)外部的數(shù)據(jù)。都可以進(jìn)行數(shù)據(jù)結(jié)構(gòu)的優(yōu)化羊初。優(yōu)化之后滨溉,都會(huì)減少其對內(nèi)存的消耗和占用什湘。
如何優(yōu)化數(shù)據(jù)結(jié)構(gòu)
1、優(yōu)先使用數(shù)組以及字符串晦攒,而不是集合類
也就是說闽撤,優(yōu)先用array,而不是ArrayList脯颜、LinkedList哟旗、HashMap等集合。
比如栋操,有個(gè)List<Integer> list = new ArrayList<Integer>()闸餐,將其替換為int[] arr = new int[]。這樣的話矾芙,array既比List少了額外信息的存儲(chǔ)開銷舍沙,還能使用原始數(shù)據(jù)類型(int)來存儲(chǔ)數(shù)據(jù),比List中用Integer這種包裝類型存儲(chǔ)數(shù)據(jù)蠕啄,要節(jié)省內(nèi)存的多场勤。
還比如,通常企業(yè)級應(yīng)用中的做法是歼跟,對于HashMap和媳、List這種數(shù)據(jù),統(tǒng)一用String拼接成特殊格式的字符串哈街,比如Map<Integer, Person> persons = new HashMap<Integer, Person>()留瞳。可以優(yōu)化為骚秦,特殊的字符串格式:id:name,address|id:name,address...她倘。
2、避免使用多層嵌套的對象結(jié)構(gòu)作箍。
比如說硬梁,public class Teacher { private List<Student> students = new ArrayList<Student>() }。就是非常不好的例子胞得。因?yàn)門eacher類的內(nèi)部又嵌套了大量的小Student對象荧止。
比如說,對于上述例子阶剑,也完全可以使用特殊的字符串來進(jìn)行數(shù)據(jù)的存儲(chǔ)跃巡。比如,用json字符串來存儲(chǔ)數(shù)據(jù)牧愁,就是一個(gè)很好的選擇素邪。
{"teacherId": 1, "teacherName": "leo", students:[{"studentId": 1, "studentName": "tom"},{"studentId":2, "studentName":"marry"}]}
3、對于有些能夠避免的場景猪半,盡量使用int替代String兔朦。
因?yàn)镾tring雖然比ArrayList偷线、HashMap等數(shù)據(jù)結(jié)構(gòu)高效多了,占用內(nèi)存量少多了烘绽,但是之前分析過淋昭,還是有額外信息的消耗。比如之前用String表示id安接,那么現(xiàn)在完全可以用數(shù)字類型的int翔忽,來進(jìn)行替代。
這里提醒盏檐,在spark應(yīng)用中歇式,id就不要用常用的uuid了,因?yàn)闊o法轉(zhuǎn)成int胡野,就用自增的int類型的id即可