在歷史長河中,各類各樣的新語言,老是伴隨着咱們編程人員;有的時候,工做的須要,咱們不得不去學習這些很炫的,很新的語言。學習任何一門語言(我這裏只說學習),都無非就是學習那麼幾個大模塊,基本語法,標準庫,函數或面向對象,內存管理。而對於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列表來調用它們的終結函數。在最後才進行這些調用是爲了簡化錯誤處理。 對於垃圾收集器的一些API,這些API,我這裏就不總結。而這篇文章也就到此結束了。一篇剪短的文章,只是帶着你們過一下啊Lua的內存管理規則,對於細節的問題,並無過多的涉及,在之後的編程中,遇到了,再細說。Lua系列也就暫時告一段落了,之後,若是遇到什麼問題,還會繼續添加新的Lua文章的。但願個人Lua系列對你們有必定的幫助,也但願你們多多給我提出一些意見。編程