,如果golang想成為主流語言,還需要解決哪些重要的問題

來源:互聯網
上載者:User

最近程式設計語言當中,golang無疑是風生水起,年度語言,伺服器端語言,並發語言,皇冠可謂不少。golang開發的初衷是替換掉c/c++,作為系統級語言,加上在1.3版本中打算將編譯系統從原來c語言開發的plan 9編譯器,改為golang實現,可謂野心勃勃。golang最令人讚美的就是簡單的文法,你可能花不了一天就能掌握golang的文法,關鍵字。golang的goroutine和channel給了大家一種簡單的並發編程模型(在此指出的是channel是另一種選擇,並不是用來替換掉Lock機制的並發編程,而是相互補助)。

在這裡,給golang潑潑冷水,或者說,如果golang想成為主流語言,還需要解決哪些重要的問題。

  1. 一個無鎖的sched調度演算法。 golang容許你建立成千上萬的goroutine,和原生系統級線程不同,goroutine的調度並不是由系統核心來完成,而是golang自己的sched調度系統來完成。golang的sched調度系統採用比較著名的work-steel演算法,大家都知道該演算法裡最核心的一個資料結構就是一個任務隊列,如何保證高並發下該隊列的正確性是該演算法的重點,比較熟悉java的同學應該知道,大師doug lea威廉叔叔的fork-join並發架構採用一個64位 volatile long欄位來保證隊列的高並發不加鎖的實現(注意volatile在java中與c++裡面的語義有區別),而golang卻採用鎖的方式來實現並發訪問,這個無疑就掉了一個檔次,好在在golang 1.3的計劃裡面已經明確將sched的無鎖列為了重要的工作。
  2. 一個更輕量級的記憶體管理架構。大家都知道google有一款很牛的效能分析和加強的架構叫google perftools,該架構裡面有一個multi-threaded malloc() 。golang內部的記憶體管理架構採用的正式該架構,所以如果是golang程式就沒有必要再連結perftools來提高效能。該架構對於一個通用架構是非常不錯的,然而golang的記憶體配置在一開始就定義好了記憶體大小,64位系統為128G記憶體,所以這種情況下的記憶體配置再簡單不過了,而採用了一個極其複雜的malloc是否有必要?雖社區時有人反應,就連russ cox也表達了需要簡化的想法,遺憾的是並沒有加入golang 1.3的計劃當中。
  3. 一個最佳化的記憶體回收演算法。 golang目前的記憶體回收機制極其幼稚,當系統使用記憶體到達上次gc回收的多少比例的時候進行一次全記憶體的標記掃描回收,預設該比例為2倍,也就是說預設下,64位系統你最多能使用64g記憶體,當然這是理想情況,現實中,你估計也不會放心在這種gc演算法下建立一個大記憶體系統。CMS在java中得到廣泛應用,也是實踐中得出最好的gc。golang如果想成為主流語言,必須在gc上和java一個層級,否則只能常常簡單golang vs Python的文章。目前來看,提高記憶體回收精度(golang在不確定記憶體中儲存的對象時,會預設4個位元組一次的依次掃描記憶體,這個實在是太慢啦),掃描階段不暫停系統比較切合實際,分代分區就要長遠來看吧。
  4. 一個Heap Dump工具。如果你不知道golang程式執行個體記憶體是如何分布的,想要最佳化你的程式,就是盲人摸象。網上有一位美團的同學,在一個線上系統中,發現使用map會使gc變慢,他只能猜測是gc對map有特殊的處理導致,其實實際的原因是一個map在gc的時候會保留一把鎖,而gc無法並發的回收該map,如果該map是一個主體結構,cms gc就變成了 單線程掃描gc了,好在該問題在golang 1.2已經修複。可喜的是golang 1.3就有可能發布heap dump工具。 採用copy stack替換現有的split stack。golang最值得誇耀的是輕量級的goroutine,goroutine的管理都有golang自己來實現,每一個goroutine都會預設在heap當中分配一個4k的記憶體塊來作為該goroutine的stack。和java不同的是,golang的stack理論上可以無限大,這要得益於golang的split stack機制,當goroutine stack滿時,golang會再分配一個塊記憶體來補充,從而形成一個無限大的stack。然而成也蕭何,敗也蕭何。當stack變小時,golang就會釋放掉閒置stack,如果一個長時間啟動並執行程式,stack肯定會頻繁的伸縮,這樣照成的記憶體配置和釋放相當頻繁,從而影響效能。好在目前ross cox已經決定採用copy stack的方式來解決該問題,而copy stack會不會造成記憶體多餘佔用的問題呢,比如一個goroutine一次大stack,以後的stack都很小,讓我們拭目以待吧。
  5. 採用copy stack替換現有的split stack。 golang最值得誇耀的是輕量級的goroutine,goroutine的管理都有golang自己來實現,每一個goroutine都會預設在heap當中分配一個4k的記憶體塊來作為該goroutine的stack。和java不同的是,golang的stack理論上可以無限大,這要得益於golang的split stack機制,當goroutine stack滿時,golang會再分配一個塊記憶體來補充,從而形成一個無限大的stack。然而成也蕭何,敗也蕭何。當stack變小時,golang就會釋放掉閒置stack,如果一個長時間啟動並執行程式,stack肯定會頻繁的伸縮,這樣照成的記憶體配置和釋放相當頻繁,從而影響效能。好在目前ross cox已經決定採用copy stack的方式來解決該問題,而copy stack會不會造成記憶體多餘佔用的問題呢,比如一個goroutine一次大stack,以後的stack都很小,讓我們拭目以待吧。

golang在文法上我想是無可挑剔了,上面是我認為golang急需解決的問題,如果能解決這些問題,特別是gc和調度,我想我會頭也不回的投入golang的陣營當中。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.