Spark中RDD提供了多種存儲級別,除去使用內存,磁盤等,還有一種是OFF_HEAP,稱之爲 使用JVM堆外內存html
使用OFF_HEAP的優勢:在內存有限時,能夠減小頻繁GC及沒必要要的內存消耗(減小內存的使用),提高程序性能。git
Spark內存管理根據版本劃分爲兩個階段:spark1.6[官網給出spark1.5以前(包含spark1.5)]以前階段、spark1.6以後階段。github
1.6.0及之後版本,使用的統一內存管理器,由UnifiedMemoryManager實現。apache
(StaticMemoryManager[https://github.com/apache/spark/blob/branch-2.4/core/src/main/scala/org/apache/spark/memory/StaticMemoryManager.scala]),編程
(UnifiedMemoryManager[https://github.com/apache/spark/blob/branch-2.4/core/src/main/scala/org/apache/spark/memory/UnifiedMemoryManager.scala])統一內存管理模塊包括了堆內內存(On-heap Memory)和堆外內存(Off-heap Memory)兩大區域併發
從1.6.0版本開始,Spark內存管理模型發生了變化。舊的內存管理模型由StaticMemoryManager類實現,如今稱爲「legacy(遺留)」。默認狀況下,「Legacy」模式被禁用,這意味着在Spark 1.5.x和1.6.0上運行相同的代碼會致使不一樣的行爲。app
爲了兼容,您可使用spark.memory.useLegacyMode參數(目前spark2.4版本中也依然保留這個靜態內存管理模型)啓用「舊」內存模型:less
spark.memory.useLegacyMode=true(默認爲false)
該參數官網給出的解釋:性能
Whether to enable the legacy memory management mode used in Spark 1.5 and before. The legacy mode rigidly partitions the heap space into fixed-size regions, potentially leading to excessive spilling if the application was not tuned. The following deprecated memory fraction configurations are not read unless this is enabled:
spark.shuffle.memoryFraction
spark.storage.memoryFraction
spark.storage.unrollFraction
在Spark1.x之前,默認的off_heap使用的是Tachyon。可是Spark中默認操做Tachyon的TachyonBlockManager開發完成以後,代碼就再也不更新。當Tachyon升級爲Alluxio以後移除不使用的API,致使Spark默認off_heap不可用(spark1.6+)。
錯誤狀況可參考:https://alluxio.atlassian.net/browse/ALLUXIO-1881
從spark2.0開始,移除默認的TachyonBlockManager以及ExternalBlockManager相關的API。
移除狀況可參考:https://issues.apache.org/jira/browse/SPARK-12667。
可是在Spark2.x的版本中,OFF_HEAP這一存儲級別,依然存在:
那麼,這裏的OFF_HEAD 數據是如何存儲的呢?
在org.apache.spark.memory中,有一個MemoryMode,MemoryMode標記了是使用ON_HEAP仍是OFF_HEAP。
在org.apache.spark.storage.memory.MemoryStore中,根據MemoryMode類型來調用不一樣的存儲。
在MemoryStore中putIteratorAsBytes方法,是用於存儲數據的方法。
其實真正管理(存儲)values的對象是valuesHolder,valueHolder是SerializedValuesHolder的類對象,咱們看下SerializedValuesHolder是怎麼定義的。
在該方法中,OFF_HEAP使用的是org.apache.spark.unsafe.Platform(https://github.com/apache/spark/blob/master/common/unsafe/src/main/java/org/apache/spark/unsafe/Platform.java)來作底層存儲的,Platform是利用java unsafe API實現的一個訪問off_heap的類,因此,spark2.x的OFF_HEAP就是利用java unsafe API實現的內存管理。
《Spark2.x 內存管理之---OFF_HEAP https://blog.csdn.net/qq_21439395/article/details/80773121》
《Java中Unsafe類詳解 https://www.cnblogs.com/mickole/articles/3757278.html 》
《JAVA併發編程學習筆記之Unsafe類 https://blog.csdn.net/aesop_wubo/article/details/7537278》