恭喜Spark2.0發佈,今天會看一下2.0的源碼。java
今天會講下Tungsten內存分配和管理的內幕。Tungsten想要工做,要有數據源和數據結構,這時候會涉及到內存管理,而內存管理也是後續作不少分析和邏輯控制的基礎。數組
咱們從內存分配的入口MemoryAllocator開始:數據結構
allocate() 分配的是一塊連續乾淨的內存空間,若是不是乾淨的話,會先用zero方法,把裏面填充爲0。咱們注意到操做的數據結構都是MemoryBlock。jvm
MemoryBlock中pageNumber字段是public級別的,方便爲TaskMemoryManager修改。內部有一個obj,onheap方式的話是一個字節數組,若是是offheap方式分配的是本地對象的指針。
其中會使用到一個Platform類,至關於Java Bean級別,提供對於數據一系列獲取方法。大數據
至於具體的內存分配是如何操做的,咱們看一下具體的實現,首先是HeapMemoryAllocator,註釋裏說明能夠分配16G原生數組。編碼
從allocate裏面看到,對於大數據量狀況,會有一個Pool來管理,Pool中會預先存放各類尺寸的memory塊,在獲取時直接獲取;小數據量的化通過字節對齊以後以後返回對象。spa
UnsafeMemoryAllocator中直接使用Platform的方法分配,這個方法沒有實現,是經過jni,用C和C++實現的,其實就是用C語言分配個空間,跟new一個數組沒有多大區別。指針
在申請內存時,若是不夠的話會spill(溢出到磁盤),以後看下release的內容,繼續進行獲取。orm
不管是UNSAFE仍是HEAP的方式,都是採用了MemoryBlock來分配,這有一個很大的好處,是讓咱們的內存使用者Task,能統一被內存的管理者TaskMemoryManager來分配.對象
TaskMemoryManager是如何來管理被task分配的內存呢,統一的方法是將地址編碼成64字節的長整數。可是對於off-heap和on-heap編碼方式是不一樣。
咱們看下TaskMemoryManager中的代碼,pageTable是個MemoryBlock的數組,會使用一個BitSet來進行索引。
最後,咱們有個問題,onheap模式下操做的時候,會根據offset來操做,有沒有說操做多大的空間?
由於地址是64位的長整數,onheap方式得到邏輯地址時,會把起始offset和長度都編碼進去,獲取64位長整數時,有一套讀取方式,雖然開始只知道offset,默認會知道下面有幾位空間,也就是數據有多長。
DT大數據天天晚上20:00YY頻道現場授課頻道68917580