Linus Torvalds是個非常厲害的程序員,因為他有兩個名揚天下的作品:Linux和Git。
如果單論技術能力,有一個人,也許比Linus更強。
我在看他主頁項目列表的時候,感覺頭都炸了。
他開發了著名的模擬器QEMU和音視頻處理庫FFmpeg,僅僅是這兩項就超越絕大部分程序員了,他還寫過C編譯器,OpenGL實現,LTE軟基站,JS引擎,讓Linux在瀏覽器中跑起來,甚至還創造了計算圓周率的世界紀錄......
也就是說,這位老兄在操作系統、模擬器、多媒體、計算機圖形學、編譯器、編程語言、通信、甚至數學等領域跳來跳去,一年開發一個我一輩子都寫不出的軟件!
他寫的程序還總是比別的程序小幾個數量級,快幾個數量級!
這也太變態了吧?!
不得不承認,這個世界上真的有天才的存在。
他就是法國程序員Fabrice Bellard。
![]()
Bellard還有個重要的特點,寫了一個厲害軟件,開創了一個領域,就把工作交給社區維護,自己拍拍屁股走人,挑戰另外一個難題。
這不,最近Fabrice Bellard又出手了,這次他帶來了一個叫做MicroQuickJS的開源項目。
這也是個JavaScript引擎,不過面向的是嵌入式設備。
我去項目主頁看了一下,好家伙,MicroQuickJS引擎運行時僅需10K的內存就可以編譯和運行JavaScript程序,在這么小的空間下,運行速度還接近QuickJS (這也是Bellard寫的另外一個輕量級的JS引擎)。
才10K! 想想Node.js,想想Chrome V8,再想想Electron,這種極致的優化能力實在是可怕。
怪不得Redis之父antirez說:如果這東西2010年就出現了,Redis的腳本語言就不會是Lua,而是JavaScript!
![]()
為什么 MicroQuickJS 可以這么小?
因為它不是在“移植 JavaScript”,而是在“重新定義 JavaScript 在嵌入式設備上該是什么樣子”。
1. 只支持 ES5 的一個“精簡版”
MicroQuickJS 支持的不是我們熟悉的那個“什么都能寫”的 JavaScript,而是一個被刻意約束過的版本。
舉幾個例子你就能理解它的取舍邏輯:
- 只支持 strict mode,不再兼容歷史包袱,行為更簡單、更可預測,也更容易優化。
- 數組不允許有“空洞”也就是說,不存在 arr[100] = 1,前面 99 個元素卻不存在的情況。這樣數組就可以用更緊湊的方式存儲,而不是像散彈槍一樣到處打洞。
- 不支持直接 eval,eval 會讓代碼在運行時突然“變身”,對內存管理和優化來說是噩夢。直接砍掉,整個引擎都清爽了。
- 日期只支持 Date.now(),不搞復雜的時區、格式化、歷史包袱,只提供“當前時間戳”這個嵌入式最常用的功能。
- 字符串大小寫轉換只支持 ASCII, 不支持完整 Unicode 的大小寫映射,換來的是代碼量和內存占用的大幅下降。
這些限制看起來有點“怪”,但你會發現它們都有一個共同目標: 確定、簡單、省內存。
2. 垃圾回收:不聰明,但非常狠
在內存只有幾十 KB 的環境里,內存碎片比“內存不夠”更致命。
MicroQuickJS 的垃圾回收策略非常直接:追蹤式+壓縮式GC。
第一層:追蹤式 GC
它從一組“根對象”開始,把所有還能被訪問到的對象標記出來,剩下的一次性全清。
不需要在每個對象上維護引用計數,不用擔心循環引用。
每個對象可以做得非常小,只需要幾個 bit 的標記信息
第二層:壓縮 GC
更狠的是:活下來的對象也不會原地不動。在回收過程中,它會把所有存活對象重新排列、擠到一塊連續的內存區域里。
內存不再被切成一地碎片,后續分配變得非常簡單,對小內存設備極其友好
MicroQuickJS 完全不用系統的 malloc,而是自己實現了一套內存分配器,這在嵌入式世界里非常重要,因為你永遠不知道系統自帶的分配器會偷偷浪費多少內存。
3. 用“變態”的方式表示 JS 的值和對象
這里是 Bellard 真正“炫技”的地方。
在 MicroQuickJS 里,一個值(數字、字符串、對象、函數等)統統只有一個 CPU 字長。
在 32 位系統上,就是 32 位,這意味著:所有值都能直接放進寄存器,傳參、賦值、判斷都極其簡單,內存布局非常規整。
對象被壓縮到了極限,一個 JavaScript 對象,最少只占 3 個 CPU 字,在 32 位系統上就是 12 字節,這已經是能做到的極限了,只夠存對象的基本類型信息和指向屬性表的指針。
屬性本身也不便宜,每個屬性至少 3 個 CPU 字,所以“隨便給對象亂加屬性”在嵌入式里是很奢侈的事。這也解釋了為什么語言層面要對動態性做那么多限制。
字符串也不走尋常路,內部存儲用的是 UTF-8(更省空間),對外仍然表現為 JavaScript 熟悉的 UTF-16 語義,也就是說,存的時候省,語義上不破壞 JS 的規則。
4. 標準庫直接“焊死”在 ROM 里
在很多 JS 引擎中,啟動時要創建 Object、Array、Math 等一大堆對象,這些對象會常駐內存,占用 RAM。
MicroQuickJS 直接換了個思路: 編譯時就把這些標準庫對象生成好,以只讀數據的形式,固化進程序鏡像,放在 ROM 里。
運行時不需要再創建,只要引用即可,啟動極快,RAM 占用極低。
總之,在嵌入式世界里,JavaScript 不再是“越全越好”,而是“剛剛好,能用就行”。
杰夫·阿特伍德(Jeff Atwood)說過,“任何可以用 JavaScript 編寫的應用程序,最終都會用 JavaScript 編寫”。
![]()
這句話現在也適用于嵌入式系統了!
也許在不就以后,我們就能在傳感器、智能家居設備和可穿戴設備上看到JavaScript。
回到作者Bellard,他為人非常低調,不拋頭露面,不寫文章,不寫書。
在互聯網上幾乎找不到對他直接的,深度采訪,只能找到他的一些只言片語,例如:“我經常會厭倦一直做同樣的事情,所以我會時不時地改變一下方向。”
由于他在如此多的領域,做出了常人根本無法企及的,不可思議的成就,有人甚至懷疑他就不是一個特定的人,而是一群人以這個id來發表軟件。
我想Bellard之所以看起來像“一群人”,并不是因為他不真實,而是因為我們早已習慣了工業化軟件生產,卻突然遇到了一個仍然生活在“個人英雄時代”的程序員。
在今天這個時代,大多數重要軟件都需要龐大的團隊、路線圖、測試、運營;而 Bellard 的作品,總是像從真空中掉下來一樣:沒有預熱、沒有宏大宣言,代碼一放出來,世界就不得不承認:規則被改寫了。
這樣的人實在是太罕見,實在是太神奇了!
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.