Ruby 2.2.0發布,支持增量式垃圾收集和符號的垃圾收集

jopen 9年前發布 | 6K 次閱讀 Ruby

Ruby 2.2.0已于2014年12月25日發布,這是給Ruby開發者的圣誕禮物。該版本的亮點包括一些垃圾收集方面的改進:引入了一個新的增量式垃圾收集算法,支持對符號(Symbol)進行垃圾收集。核心類和標準庫方面也有小幅改進。

Ruby 2.2.0發布,支持增量式垃圾收集和符號的垃圾收集

根據Ruby 2.1.0中 分代垃圾收集(RGenGC)相關的說明,分代方式可以改進GC吞吐量。在新版本中,Ruby的維護者繼續引入了重要的改進。大部分對象都會在很年輕的時 候死掉,根據這個假設,分代垃圾收集將對象分為幾個代。這個假設使得對較年輕對象的處理有較高的吞吐量和較低的延遲,因為較老的對象會在內存不足時才去計 算是否要刪除。不過也意味著,較老的對象仍然要承受高延遲之困。

增量式垃圾收集(RIncGC)是在分代垃圾收集的基礎上構建的,致力于在維持同樣吞吐量的前提下減少停頓時間。通過將標記階段(把對象標記為可以進行垃圾收集)與Ruby的正常執行交錯進行,較少了停頓時間。而在Ruby 2.2.0之前,標記階段要占用很大的一步。

RGenGC和RIncGC都不能管理所有對象,意味著某些對象不會被提升到較老的一代。主要是因為C擴展,無法保證全部滿足RGenGC和RIncGC的約束。在RubyConf 2014大會上, Koichi Sasada詳細描述了RGenGC和RIncGC。如果想了解所有的算法細節和性能基準測試,這是很好的材料。

Ruby 2.2.0發布,支持增量式垃圾收集和符號的垃圾收集

全局停頓GC與增量式GC之對比 來源:Koichi Sasada

Ruby 2.2.0發布,支持增量式垃圾收集和符號的垃圾收集

RIncGC消除了長期停頓 來源:Koichi Sasada

Ruby 2.2.0引入的對符號的垃圾收集,也改進了Ruby的內存管理。這個改進如此之大,乃至計劃于2015年秋季發布的Ruby on Rails 5.0,將僅支持Ruby 2.2及以上的版本。

Rails 5.0將僅支持Ruby 2.2及以上的版本。Ruby 2.2帶來的很多優化都非常棒,但是對Rails而言,符號的垃圾收集是最重要的。這意味著在處理來自外部的字符串時,可以輕松很多。而且我們可以完全轉 換到最新的Ruby帶來的關鍵字參數(keyword arguments)和其他所有良好特性。

因為Ruby內部會將每個符號映射到一個整形數(integer),帶來了一個問題。CRuby(用C實現的Ruby) 將這個整形數用作符號的ID。如果一個符號在Ruby端釋放了,之后又創建了同樣的字符串,那會出現不同的CRuby整形數ID。這意味著,根據語言規范 是同樣的符號,但是出現了不同的ID,所以是個bug。

最簡單的解決方案是用字符串替換CRuby中的整形數,這樣在兩端(C和Ruby)就一致了。另外,C擴展將問題變得更 復雜了,因為它們會妨礙運行時探測和管理所有的符號。解決方案是將符號分成兩組:永久的(immortal)和非永久的(mortal)。永久的符號會繼 續使用整形數ID,不會被回收。這類例子包括方法名、變量名、常量和其他語言元素。非永久的符號,比如"foo".to_sym,沒有整形數ID,可以被 回收。

Ruby 2.2.0發布,支持增量式垃圾收集和符號的垃圾收集

非永久的符號與永久的符號之對比 來源:Narihiro Nakamura

Narihiro Nakamura在RubyKaigi2014大會上描述了符號GC的解決方案,還介紹之所以使用這種方案的所有約束條件。

仍然是內存管理方面,Ruby 2.2.0還提供了一個選擇,即使用jemalloc代替系統的malloc,此舉有可能會提高速度,并減少內存碎片。這還是一個實驗性特性,在收集到更多性能數據和使用案例后才會正式提供。

諸如system()和spawn()等創建進程的方法,在可能的情況下會使用vfork(2),代替了fork()。這種改變也會提高性能,尤其是當父進程會消耗大量內存時。這也是個實驗性特性,未來可能會發生變化。

核心庫現已支持Unicode 7.0,還引入了一些新方法,如Enumerable#slice_afterEnumerable#slice_whenFloat#next_float、Float#prev_floatFile.birthtime、File#birthtimeString#unicode_normalize

Ruby 2.2.0廢棄了mathn庫,同時還更新了其他一些庫:

  • Psych 2.0.8
  • Rake 10.4.2
  • RDoc 4.2.0
  • RubyGems 2.4.5
  • test-unit 3.0.8
  • minitest 5.4.3

更多細節,包括廢棄的一些C API以及一些非兼容的改變,詳見Ruby 2.2.0相關新聞。與Ruby 2.1.0相比,Ruby 2.2.0有1557處文件改動,包括125039條插入和74376條刪除。

原文: http://www.infoq.com/news/2014/12/ruby-2.2.0-released 作者: Jo?o Miranda

譯文: http://www.infoq.com/cn/news/2015/01/ruby-2.2.0-released 譯者: 臧秀濤

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!