Spark - 利用WeakReference來(lái)清理對(duì)象

注:本文轉(zhuǎn)自我的個(gè)人博客(Spark - 利用WeakReference來(lái)清理對(duì)象)鸠天。

最近在stackoverflow上看到有人好奇Spark是在什么時(shí)機(jī)對(duì)Accumulator或者Broadcast這樣的變量進(jìn)行回收的镀脂。自己在看源碼的時(shí)候發(fā)現(xiàn)了這個(gè)有趣的地方。


Spark ContextCleaner

我們?cè)赟park閑置(沒(méi)有任務(wù)執(zhí)行)時(shí)酒觅,容易看到下面的日志:

19/02/12 05:19:51 INFO Spark Context Cleaner org.apache.spark.internal.Logging$class.logInfo(Logging.scala:54): Cleaned accumulator 108284023
19/02/12 05:19:51 INFO Spark Context Cleaner org.apache.spark.internal.Logging$class.logInfo(Logging.scala:54): Cleaned accumulator 108283658

追溯到源碼中撮执,可以得知SparkContext在啟動(dòng)時(shí),初始化了ContextCleaner舷丹,并以daemon方式啟動(dòng)了一個(gè)cleaningThread線程抒钱,這個(gè)線程的作用就是不斷循環(huán),回收清理RDD颜凯、Broadcast變量谋币、Accumulator等無(wú)效對(duì)象。
這個(gè)時(shí)候可以提出一個(gè)問(wèn)題:以Accumulator為例症概,當(dāng)某個(gè)Accumulator不再使用(沒(méi)有被任何對(duì)象引用)時(shí)蕾额,ContextCleaner是如何知道這個(gè)信息的?

先看一下整個(gè)清理過(guò)程:

val reference = Option(referenceQueue.remove(ContextCleaner.REF_QUEUE_POLL_TIMEOUT))
  .map(_.asInstanceOf[CleanupTaskWeakReference])
// Synchronize here to avoid being interrupted on stop()
synchronized {
  reference.foreach { ref =>
    logDebug("Got cleaning task " + ref.task)
    referenceBuffer.remove(ref)
    ref.task match {
      case CleanRDD(rddId) =>
        doCleanupRDD(rddId, blocking = blockOnCleanupTasks)
      case CleanShuffle(shuffleId) =>
        doCleanupShuffle(shuffleId, blocking = blockOnShuffleCleanupTasks)
      case CleanBroadcast(broadcastId) =>
        doCleanupBroadcast(broadcastId, blocking = blockOnCleanupTasks)
      case CleanAccum(accId) =>
        doCleanupAccum(accId, blocking = blockOnCleanupTasks)
      case CleanCheckpoint(rddId) =>
        doCleanCheckpoint(rddId)
    }
  }
}

可以看到彼城,ContextCleaner是通過(guò)一個(gè)referenceQueue找到了需要回收的對(duì)象(CleanAccum)诅蝶。接下來(lái),從referenceQueue入手募壕,看看JVM中的WeakReference是什么樣的存在调炬。


Java WeakReference

Java中對(duì)Reference有幾種不同的分類:

  • StrongReference: 通常我們定義的對(duì)象就屬于這種,較難被GC舱馅。
  • WeakReference: 如Spark中封裝的CleanupTaskWeakReference(task, objectForCleanup, referenceQueue) 缰泡,如果引用的對(duì)象(task)只和當(dāng)前的WeakReference對(duì)象聯(lián)結(jié),那么在GC中會(huì)被回收代嗤,并放入referenceQueue中匀谣。
  • SoftReference: 相對(duì)WeakReference較強(qiáng)的引用,可以回收资溃,但不一定是在下次GC中武翎。

所以在ContextCleaner中,Spark采用了WeakReference + referenceQueue的方式來(lái)實(shí)現(xiàn)對(duì)象的回收溶锭。當(dāng)我們注冊(cè)一個(gè)Accumulator時(shí)宝恶,會(huì)同時(shí)調(diào)用registerForCleanup:

/** Register an object for cleanup. */
private def registerForCleanup(objectForCleanup: AnyRef, task: CleanupTask): Unit = {
  referenceBuffer.add(new CleanupTaskWeakReference(task, objectForCleanup, referenceQueue))
}

referenceBuffer的作用是保證WeakReference在處理前不被GC。

Spark將注冊(cè)的Accumulator封裝到CleanupTask,并基于task初始化了一個(gè)WeakReference垫毙。當(dāng)Accumulator不再被引用時(shí)霹疫,task會(huì)被放入referenceQueue中,而此時(shí)cleaningThread從referenceQueue中提取即將要GC的對(duì)象做處理(見(jiàn)上面的清理過(guò)程代碼)综芥。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丽蝎,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子膀藐,更是在濱河造成了極大的恐慌屠阻,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,692評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件额各,死亡現(xiàn)場(chǎng)離奇詭異国觉,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)虾啦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門麻诀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人傲醉,你說(shuō)我怎么就攤上這事蝇闭。” “怎么了硬毕?”我有些...
    開(kāi)封第一講書人閱讀 162,995評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵丁眼,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我昭殉,道長(zhǎng)苞七,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,223評(píng)論 1 292
  • 正文 為了忘掉前任挪丢,我火速辦了婚禮蹂风,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘乾蓬。我一直安慰自己惠啄,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布任内。 她就那樣靜靜地躺著撵渡,像睡著了一般。 火紅的嫁衣襯著肌膚如雪死嗦。 梳的紋絲不亂的頭發(fā)上趋距,一...
    開(kāi)封第一講書人閱讀 51,208評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音越除,去河邊找鬼节腐。 笑死外盯,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的翼雀。 我是一名探鬼主播饱苟,決...
    沈念sama閱讀 40,091評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼狼渊!你這毒婦竟也來(lái)了箱熬?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 38,929評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤狈邑,失蹤者是張志新(化名)和其女友劉穎城须,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體官地,經(jīng)...
    沈念sama閱讀 45,346評(píng)論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評(píng)論 2 333
  • 正文 我和宋清朗相戀三年烙懦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了驱入。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,739評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡氯析,死狀恐怖亏较,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情掩缓,我是刑警寧澤雪情,帶...
    沈念sama閱讀 35,437評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站你辣,受9級(jí)特大地震影響巡通,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜舍哄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評(píng)論 3 326
  • 文/蒙蒙 一宴凉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧表悬,春花似錦弥锄、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,677評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至饭庞,卻和暖如春戒悠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背舟山。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,833評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工救崔, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惶看,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,760評(píng)論 2 369
  • 正文 我出身青樓六孵,卻偏偏與公主長(zhǎng)得像纬黎,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子劫窒,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容