【前言】
在歷史長河中,各種各樣的新語言,總是伴隨著我們程式設計人員;有的時候,工作的需要,我們不得不去學習這些很炫的,很新的語言。學習任何一門語言(我這裡只說學習),都無非就是學習那麼幾個大模組,基本語法,標準庫,函式或物件導向,記憶體管理。而對於lua的學習,前面幾個模組我都已經總結完畢了,而今天這篇文章主要是總結lua中的記憶體管理。
lua在兩個層面提供了對這些定製的支援。在較低層面,可以設定lua使用的分配函式;在較高層面,可以設定一些控制垃圾收集器的引數,或者直接控制垃圾收集器。現在就開始這一篇的旅行吧。
【分配函式】
lua是通過乙個「分配函式」來完成所有的記憶體分配和釋放操作。當使用者建立乙個lua狀態時,必須提供這個函式。之前的**中總是會用到乙個lual_newstate輔助函式,這個函式會以乙個預設的分配函式來建立lua狀態。預設的分配函式使用了c標準庫中的malloc-realloc-free函式,對於普通的應用程式這已經足夠了,然而,要獲取對lua記憶體分配的完全控制也是非常容易的,只需要用原始的lua_newstate來建立狀態就可以了:
lua_state *lua_newstate(lua_alloc f, void *ud);
這個函式接收兩個引數:分配函式和使用者資料。以這種方式建立的狀態會呼叫f來完成所有的記憶體分配和釋放。由於分配記憶體的策略很多,而對於lua_alloc分配函式的分析和講解,也不是這篇文章的重點;這篇文章,只是對lua記憶體管理進行簡單的說明,讓你知道有這麼個東西,有這麼回事,那麼我的這篇文章就達到目的了。
【垃圾收集器】
lua在5.0版之前,都是採用的一種簡單的「標記並清理」的垃圾收集器。這種垃圾清理的每個週期由4個階段組成:標記、整理、清掃和收尾。lua有時會為了完成乙個完整的垃圾收集週期而暫停與主程式的互動。接下來,就對乙個垃圾清理週期中的每個階段進行詳細的說明。
在標記階段,lua先將「根集合」中的物件標記為「活躍」。根集合中的物件就是lua可以直接訪問的物件,它們是登錄檔中的物件和主線程物件。然後,lua將任何程式可以通過根集合物件訪問到的物件也都標記為「活躍」。這樣會使所有可到達的物件都標記為「活躍」了。
在開始清掃階段前,lua先要進入整理階段。這個階段為「終結函式」和弱引用table。首先,lua遍歷所有的userdata,找出所有未被標記且具有–gc元方法的userdata。然後,將這些userdata標記為「活躍」,並放入乙個單獨的列表中。這個列表在收尾階段會用到。另一方面,lua還會遍歷所有的弱引用table,並根據弱引用設定刪除其中未被標記的key和value。
在清掃階段中,lua遍歷所有的物件。如果當前遍歷到的物件未被標記,就收集它。否則,lua就清除它的標記,從而為下乙個收集週期做準備。
最後是收尾階段,其中會根據整理階段中生成的userdata列表來呼叫它們的終結函式。在最後才進行這些呼叫是為了簡化錯誤處理。
記憶體管理 記憶體管理概述
儲存器的發展方向是高速 大容量和小體積,即儲存器嘗試更高讀寫速度,更大儲存容量,更小物理體積。在計算機中,常見的儲存器有 暫存器,快取,記憶體,硬碟,一般硬碟之類的輔助儲存器又稱外存。在平均讀寫速度上,有 暫存器 快取 記憶體 外存 在單位容量 上,有 外存 記憶體 快取 暫存器 cpu處理器只能直...
記憶體管理 記憶體的簡介
32位機器具有4g的程式記憶體,這個記憶體並不是指實際的物理記憶體,而是虛擬記憶體這個虛擬記憶體並不是實際存在的。我們知道乙個虛擬空間由一組頁對映函式將虛擬空間的各個頁對映至相應的物理空間,那麼建立乙個虛擬空間實際上並不是建立空間而是建立對映函式所需要的相應的資料結構,在i386 的linux下,建...
記憶體的管理
記憶體的管理大致分為有作業系統 os 的和沒有作業系統的。一 沒有os 沒有作業系統的時候,計算機執行的就是裸機程式,記憶體的開闢和釋放全部由裸機程式自己承擔。二 有os 有作業系統的時候,作業系統會幫助我們管理記憶體空間,並且留下一些簡潔的記憶體管理介面,便於我們能夠直接控制記憶體的管理。但是相比...