Go語言記憶體管理(一)記憶體分配

来源:https://www.cnblogs.com/ldaniel/archive/2018/03/03/8502867.html
-Advertisement-
Play Games

Go語言記憶體管理(一)記憶體分配 golang作為一種“高級語言”,也提供了自己的記憶體管理機制。這樣一方面可以簡化編碼的流程,降低因記憶體使用導致出現問題的頻率(C語言使用者尤其是初學者應該深有體會),對程式猿友好。另一方面也可以減少記憶體相關係統調用,提升性能。 先瞭解下記憶體管理大致策略: 申請一塊較大 ...


Go語言記憶體管理(一)記憶體分配

golang作為一種“高級語言”,也提供了自己的記憶體管理機制。這樣一方面可以簡化編碼的流程,降低因記憶體使用導致出現問題的頻率(C語言使用者尤其是初學者應該深有體會),對程式猿友好。另一方面也可以減少記憶體相關係統調用,提升性能。

先瞭解下記憶體管理大致策略:

  • 申請一塊較大的地址空間(虛擬記憶體),用於記憶體分配及管理(golang:spans+bitmap+arena->512M+16G+512G)
  • 當空間不足時,向系統申請一塊較大的記憶體,如100KB或者1MB
  • 申請到的記憶體塊按特定的size,被分割成多種小塊記憶體(golang:_NumSizeClasses = 67),並用鏈表管理起來
  • 創建對象時,按照對象大小,從空閑鏈表中查找到最適合的記憶體塊
  • 銷毀對象時,將對應的記憶體塊返還空閑鏈表中以復用
  • 空閑記憶體達到閾值時,返還操作系統

以下,基於go1.9版本,看下golang記憶體分配實現的基本思路。

Go記憶體管理的實現

go的記憶體管理實現基於TCMalloc(Thread-Caching Malloc)。

TCMalloc是 Google 開發的多級記憶體分配器,具有對抗記憶體碎片化,適合高併發場景的特性。據稱,它的記憶體分配速度是 glibc2.3 中實現的 malloc的數倍。

和TCMalloc相同,go的記憶體分配也是基於兩種粒度的記憶體單位:span和object。span是連續的page,按page的數量進行歸類,比如分為2個page的span,4個page的span等。object是span中按預設大小劃分的塊,也是按大小分類。同一個span中,只有一種類型(大小)的object。

go記憶體分配主要有三個管理組件:

  • mcache

Per-P(Processer,具體參見go中G,M,P的概念)私有cache,用於實現無鎖的object分配

  • mcentral

全局記憶體,為各個cache提供按大小劃分好的span

  • mheap

全局記憶體,page管理,記憶體不足時向系統申請

通過將記憶體分配流程分為三個層級,既能保證Processer級別(mcache)的無鎖分配,又能在mcentral級別實現記憶體全局共用,避免浪費。

go將記憶體申請按大小分為三種類型:tiny,small,large。tiny是小於16個byte的申請,small是小於32KB的申請,大於32KB為large,三種類型的處理方式有所不同。

_TinySize      = 16
_MaxSmallSize   = 32768

我們以一個small對象為例,看一下記憶體申請流程:

  1. 計算對象大小,按預定義的sizeclass表(見下)從私有的mcache中找到對應規格的mspan。比如大小為112 byte的對象,對應8192 byte大小的mspan。然後通過mspan的空閑bitmap查找空閑的塊,如果空閑塊存在,分配完成。

以上是mcache內的分配操作,不需要加鎖。

  1. 如果mspan沒有空閑塊,則向mcentral申請對應大小的空閑mspan。比如112 byte的對象,需要向mcentral申請8192 byte大小的空閑mspan。

由於申請獲取全局的mspan,需要在mcentral級別加鎖。

  1. 如果mcentral中沒有空閑mspan,則向mheap申請,並劃分object。

  2. 如果mheap沒有足夠的空閑page,則向操作系統申請不少於1M的page。

以上就是small對象的記憶體分配流程。

large對象的申請,跳過了mcache和mcentral,直接從mheap中分配。

對於tiny對象的申請,mcache中有專門的記憶體區域“tiny”來進行特殊處理。“tiny”將對象按大小與tinyoffset(“tiny”當前分配地址)對齊,然後分配,並記錄下新的tinyoffset,用於下次分配。如果空間不足,則另外申請16 byte的記憶體塊。

// sizeclass
// class  bytes/obj  bytes/span  objects  waste bytes
//     1          8        8192     1024            0
//     2         16        8192      512            0
//     3         32        8192      256            0
//     4         48        8192      170           32
//     5         64        8192      128            0
//     6         80        8192      102           32
//     7         96        8192       85           32
//     8        112        8192       73           16
//     9        128        8192       64            0
//    10        144        8192       56          128
//    11        160        8192       51           32
//    12        176        8192       46           96
//    13        192        8192       42          128
//    14        208        8192       39           80
//    15        224        8192       36          128
//    16        240        8192       34           32
//    17        256        8192       32            0
//    18        288        8192       28          128
//    19        320        8192       25          192
//    20        352        8192       23           96
//    21        384        8192       21          128
//    22        416        8192       19          288
//    23        448        8192       18          128
//    24        480        8192       17           32
//    25        512        8192       16            0
//    26        576        8192       14          128
//    27        640        8192       12          512
//    28        704        8192       11          448
//    29        768        8192       10          512
//    30        896        8192        9          128
//    31       1024        8192        8            0
//    32       1152        8192        7          128
//    33       1280        8192        6          512
//    34       1408       16384       11          896
//    35       1536        8192        5          512
//    36       1792       16384        9          256
//    37       2048        8192        4            0
//    38       2304       16384        7          256
//    39       2688        8192        3          128
//    40       3072       24576        8            0
//    41       3200       16384        5          384
//    42       3456       24576        7          384
//    43       4096        8192        2            0
//    44       4864       24576        5          256
//    45       5376       16384        3          256
//    46       6144       24576        4            0
//    47       6528       32768        5          128
//    48       6784       40960        6          256
//    49       6912       49152        7          768
//    50       8192        8192        1            0
//    51       9472       57344        6          512
//    52       9728       49152        5          512
//    53      10240       40960        4            0
//    54      10880       32768        3          128
//    55      12288       24576        2            0
//    56      13568       40960        3          256
//    57      14336       57344        4            0
//    58      16384       16384        1            0
//    59      18432       73728        4            0
//    60      19072       57344        3          128
//    61      20480       40960        2            0
//    62      21760       65536        3          256
//    63      24576       24576        1            0
//    64      27264       81920        3          128
//    65      28672       57344        2            0
//    66      32768       32768        1            0

參考文獻:

TCMalloc

圖解 TCMalloc


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 覆選框checkbox和單選框radio是web網站里經常會使用到的兩個控制項,那麼在web自動化測試的時候如何利用Selenium來操作這倆控制項呢?今天我們就來簡單入門練習一下! html測試頁面代碼如下: 從HTML代碼看,這裡面的覆選框checkbox和單選框radio都是input標簽,那麼我 ...
  • 解法一: 這種解法使用的是Brute Force演算法,即是暴力搜索匹配,時間複雜度較高 解法二: 這種解法的思想是計算兩個相同的字元之間的長度,好比作一個視窗在字元串上右邊框向右拉伸,若右邊框碰到視窗內已存在的字元,那麼左邊框向右拉伸到到視窗已存在字元的右邊,時間複雜度較低 github地址:htt ...
  • 研究了一些操作系統的概念,研究了I/O模式,著重研究了select、poll、epoll 的區別, ...
  • (一) 字元串 單引號、雙引號、三重引號都可以作為字元串的開始和結束,三重引號可以直接輸入多行字元串。三重引號可能一般是用來寫多行註釋。 (二) r和\ r使字元串成為原始字元串,忽略所有轉義字元。 \是轉義字元。 (三) 字元串下標和切片 (四) 字元串的in和not in (五) 改變大小寫 方 ...
  • 事先聲明,我只是java併發的新手,這篇文章也只是我閱讀《java併發編程的藝術》一書(內容主要涉及前3章)的一些總結和感悟。希望大家能多多討論,對於錯誤的地方還請指出。 0. 簡介 程式的世界是有層次分明的,每層都對外封裝細節而提供一些方式或者說介面來提供功能,甚至是約束功能來換取正確性等等。那麼 ...
  • SpringBoot中關於Mybatis使用的三個問題 轉載請註明源地址:http://www.cnblogs.com/funnyzpc/p/8495453.html 原本是要講講PostgreSQL的一些學習總結的,不巧的是最近一段時間的進度都是一些類似於加減乘除、位移、類型轉換的稍顯小兒科的一些 ...
  • istringstream用於執行C++風格的串流操作。 下麵的示例是使用一個字元串初始化istringstream類,然後再使用>>操作符來依次輸出字元串中的內容。 ...
  • 截止目前已經改造了5個類: ubuntu:通過封裝驗證碼類庫一步步安裝php的gd擴展 自定義MVC框架之工具類-分頁類的封裝 自定義MVC框架之工具類-文件上傳類 自定義MVC框架之工具類-圖像處理類 這個模型類支持以下功能: >連貫操作,js叫鏈式操作,連貫操作的函數可以打亂順序,最後一個函數必 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...