一、記憶體都花費在哪裡了?
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、首先,自己設定RDD的並行度,有兩種方式:要不然,在parallelize()、textFile()等方法中,傳入第二個引數,設定RDD的task / partition的數量;要不然,用SparkConf.set()方法,設定一個引數,spark.default.parallelism,可以統一設定這個application所有RDD的partition數量。
2、其次,在程式中將RDD cache到記憶體中,呼叫RDD.cache()方法即可。
3、最後,觀察Driver的log,你會發現類似於:“INFO BlockManagerMasterActor: Added rdd_0_1 in memory on mbk.local:50311 (size: 717.5 KB, free: 332.3 MB)”的日誌資訊。這就顯示了每個partition佔用了多少記憶體。
4、將這個記憶體資訊乘以partition數量,即可得出RDD的記憶體佔用量。