C庫緩存
erts_alloc框架
庫摘要工具
Erlang運行時系統內部內存分配器庫。性能
描述spa
erts_alloc是一個Erlang運行時系統內部內存分配器庫。 erts_alloc爲Erlang運行時系統提供了許多內存分配器。操作系統
分配器命令行
存在如下分配器:線程
temp_alloc對象
用於臨時分配的分配器。進程
eheap_alloc
用於Erlang堆數據(例如Erlang進程堆)的分配器。
binary_alloc
用於Erlang二進制數據的分配器。
ets_alloc
用於ets數據的分配器。
driver_alloc
用於驅動程序數據的分配器。
literal_alloc
用於Erlang代碼中常數項的分配器。
sl_alloc
用於預期壽命短的內存塊的分配器。
ll_alloc
用於預期壽命長的內存塊的分配器,例如,Erlang代碼。
fix_alloc
一種快速分配器,用於某些經常使用的固定大小的數據類型。
exec_alloc
HiPE應用程序用於本機可執行代碼的分配器。
std_alloc
未用於經過上述任何其餘分配器分配的大多數內存塊的分配器。
sys_alloc
一般,這是特定操做系統上使用的默認malloc實現。
mseg_alloc
內存段分配器。其餘分配器使用它來分配內存段,而且僅在具備mmap系統調用的系統上可用。被釋放的內存段在銷燬以前會在段緩存中保留一段時間。分配段後,將盡量使用緩存的段,而不是建立新的段。這樣能夠減小進行系統調用的次數。
sys_alloc,literal_alloc和temp_alloc始終啓用,不能禁用。 exec_alloc僅在須要時可用,不能禁用。 若是可用,而且啓用了使用它的分配器,則始終啓用mseg_alloc。 全部其餘分配器均可以啓用或禁用。 默認狀況下,全部分配器都是啓用的。 禁用分配器後,將使用sys_alloc代替禁用的分配器。
erts_alloc庫的主要思想是將不一樣使用的內存塊分離到不一樣的內存區域,以減小內存碎片。 與爲那些不那麼頻繁分配的內存塊相比,經過花更少的精力找到適合於頻繁分配的內存塊的性能,能夠實現性能提高。
alloc_util框架
在內部,稱爲alloc_util的框架用於實現分配器。 sys_alloc和mseg_alloc不使用此框架,所以如下內容不適用於它們。
分配器管理多個區域,這些區域稱爲載體,在其中放置了內存塊。 載體能夠放在單獨的內存段中(經過mseg_alloc分配),也能夠放在堆段中(經過sys_alloc分配)。
一般,分配器建立「主多塊載體」。 主多塊載體永遠不會釋放。 主多塊載體的大小由參數mmbcs的值肯定。
經過mseg_alloc分配的多塊載體的大小取決於如下參數:
若是nc是分配器管理的當前多塊載體數(不包括主多塊載體),則當nc<=mbcgs時,此分配器分配的下一個mseg_alloc多塊載體的大小約爲smbcs + nc *(lmbcs-smbcs)/ mbcgs,nc> mbcgs時,爲lmbcs。 可是,若是參數sbct的值大於參數lmbcs的值,則分配器可能必須建立大於參數lmbcs的值的多塊載體。 經過mseg_alloc分配的單塊載體大小爲整頁。
經過sys_alloc分配的載體大小取決於sys_alloc載體大小(ycs)參數的值。 載體的大小是知足請求的參數ycs的值的最小倍數。
空閒塊的合併始終當即執行。 使用自由塊中的邊界標記(頁眉和頁腳),這使得合併的時間複雜度恆定。
可使用參數as配置分配器用於多塊載波的內存分配策略。 可使用如下策略:
Best fit
策略:查找知足請求塊大小的最小塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的大小數。
Address order best fit
策略:查找知足請求塊大小的最小塊。 若是找到多個塊,則選擇地址最低的那個。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Address order first fit
策略:查找地址知足要求的塊大小最低的塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Address order first fit carrier best fit
策略:找到地址最低且可知足請求的塊大小的載體,而後使用「最適合」策略在該載體內找到一個塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Address order first fit carrier address order best fit
策略:找到可知足請求塊大小的最低地址的載體,而後使用「地址順序最適合」策略在該載體中找到一個塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Age order first fit carrier address order first fit
策略:找到能夠知足請求的塊大小的最先的載體,而後使用「地址順序優先」策略在該載體中找到一個塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Age order first fit carrier best fit
策略:找到能夠知足請求的塊大小的最先的載體,而後使用「最適合」策略在該載體中找到一個塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Age order first fit carrier address order best fit
策略:找到能夠知足請求的塊大小的最先的載體,而後使用「地址順序最適合」策略在該載體中找到一個塊。
實現:使用平衡的二進制搜索樹。 時間複雜度與log N成正比,其中N是空閒塊的數量。
Good fit
策略:嘗試找到最合適的,但要在有限的搜索中找到最合適的。
實現:該實現使用最大塊搜索深度(在每一個列表中)的隔離的空閒列表來快速找到合適的對象。 當最大塊搜索深度較小時(默認爲3),此實現的時間複雜度是恆定的。 可使用參數mbsd配置最大塊搜索深度。
A fit
策略:不要尋找合適的位置,僅檢查一個空閒塊以查看其是否知足要求。 此策略僅用於臨時分配。
實現:檢查空閒列表中的第一個塊。 若是知足請求,則使用該請求,不然建立新的載體。 該實現具備恆定的時間複雜度。
從ERTS 5.6.1開始,仿真器拒絕在temp_alloc以外的其餘分配器上使用此策略。 這是由於它只會給其餘分配器帶來問題。
除了上述普通分配器以外,一些預分配器還用於某些特定的數據類型。 運行系統啓動時,這些預分配器會爲某些數據類型預分配固定數量的內存。 只要有預分配的內存可用,就可使用它。 當沒有可用的預分配內存時,將在普通分配器中分配內存。 這些預分配器一般比普通分配器快得多,但只能知足有限數量的請求。
影響erts_alloc的系統標誌
警告:僅在肯定本身在作什麼時才使用這些標誌。 不合適的設置可能會致使嚴重的性能降低,甚至在運行期間的任什麼時候間致使系統崩潰。
內存分配器系統標誌具備如下語法:+ M <S> <P> <V>,其中<S>是標識子系統的字母,<P>是參數,而<V>是要使用的值。 能夠將這些標誌做爲命令行參數傳遞給Erlang仿真器(erl(1))。
影響特定分配器的系統標誌的大寫字母爲<S>。 如下字母用於分配器:
B: binary_alloc
D: std_alloc
E: ets_alloc
F: fix_alloc
H: eheap_alloc
I: literal_alloc
L: ll_alloc
M: mseg_alloc
R: driver_alloc
S: sl_alloc
T: temp_alloc
X: exec_alloc
Y: sys_alloc
mseg_alloc的配置標誌
+MMamcbf <size>
絕對最大高速緩存不合適(以千字節爲單位)。 若是內存段緩存中的某個段的大小超過了所請求的大小且大於此參數的值,則不會重用該段。 默認爲4096。
+MMrmcbf <ratio>
相對最大高速緩存不合適(百分比)。 若是內存段緩存中的某個段的大小超過了請求的大小,而且超過了請求大小的相對最大緩存不適合百分比,則該段不會被重用。 默認爲20。
+MMsco true|false
設置僅超級載體標誌。 默認爲true。 當使用超級載體且此標誌爲true時,mseg_alloc僅在超級載體中建立載體。 請注意,alloc_util框架能夠建立sys_alloc載體,所以,若是要在超級載體中建立全部載體,則但願經過傳遞+ Musac false來禁用sys_alloc載體的使用。 當該標誌爲false時,當超級載體已滿時,mseg_alloc嘗試在超級載體以外建立載體。
注意:並不是全部系統都支持將此標誌設置爲false。 該標誌而後被忽略。
+MMscrfsd <amount>
設置超級載體保留的自由段描述符。 默認值爲65536。此參數肯定爲超級載體使用的空閒段描述符保留的內存量。 若是系統用完了空閒段描述符的保留內存,則將使用其餘內存。 可是,這可能會致使碎片問題,所以您要確保這種狀況永遠不會發生。 能夠從調用erlang:system_info({allocator,mseg_alloc})的結果的erts_mmap元組部分中檢索使用的最大空閒段描述符數量。
+MMscrpm true|false
設置超級載體保留物理內存標誌。 默認爲true。 當此標誌爲true時,物理內存在建立時將當即爲整個超級載體保留。 此後保留保留不變。 當此標誌設置爲false時,在建立時僅爲超級載體保留虛擬地址空間。 系統嘗試在超級載體中建立載體時保留物理內存,並嘗試在超級載體中破壞載體時取消物理內存。
注意:
物理內存的保留意味着什麼,在很大程度上取決於操做系統及其配置。 例如,Linux上不一樣的內存過量使用設置會極大地改變行爲。
並不是全部系統都支持將此標誌設置爲false。 該標誌而後被忽略。
+MMscs <size in MB>
設置超級載體大小(以MB爲單位)。 默認爲0,即默認狀況下禁用超級載體。 超級載體是虛擬地址空間中的一個大連續區域。 若是存在,則mseg_alloc始終嘗試在超級載體中建立新載體。 注意,alloc_util框架能夠建立sys_alloc載體。 有關更多信息,請參見+ MMsco。
+MMmcs <amount>
最大緩存段。 存儲在內存段緩存中的最大內存段數。 有效範圍是[0,30]。 默認爲10。
用於配置sys_alloc的標誌
+MYe true
啓用sys_alloc。
注意:sys_alloc沒法禁用。
+MYm libc
要使用的malloc庫。 僅libc可用。 libc啓用標準libc malloc實現。 默認狀況下使用libc。
+MYtt <size>
修剪閾值大小(以千字節爲單位)。 這是malloc(不釋放給操做系統)保留的堆(由sbrk分配)頂部的最大可用內存量。 當堆頂部的可用內存量超過修剪閾值時,malloc釋放它(經過調用sbrk)。 修剪閾值以千字節爲單位指定。 默認值爲128。
注意:僅當仿真器與GNU C庫連接並使用其malloc實現時,此標誌纔有效。
+MYtp <size>
Top pad大小(以千字節爲單位)。 這是當調用sbrk從操做系統獲取更多內存時,malloc分配的額外內存量。 預設爲0。
注意:僅當仿真器與GNU C庫連接並使用其malloc實現時,此標誌纔有效。
基於alloc_util的分配器配置標誌
若是將u用做子系統標識符(即<S> = u),則全部基於alloc_util的分配器都會生效。 若是將B,D,E,F,H,L,R,S或T用做子系統標識符,則僅實現特定的分配器標識符。
+M<S>acul <utilization>|de
放棄載體利用率限制。有效的<utilization>是[0,100]範圍內的整數,以百分比表示利用率。使用利用率值> 0時,容許分配器實例放棄多塊載體。若是傳遞了de(默認啓用)而不是<utilization>,則使用建議的非零利用率值。選擇的值取決於分配器類型,而且能夠在ERTS版本之間進行更改。默認爲de,可是未來能夠更改。
當分配器實例中的內存利用率低於所使用的利用率值時,將放棄載體。一旦放棄了載體,便不會在其中進行新的分配。當分配器實例得到增長的多塊載體需求時,它首先嚐試從相同分配器類型的分配器實例中獲取廢棄的載體。若是沒法獲取任何廢棄的載體,則會建立一個新的空載體。提取廢棄的載體後,它將充當普通載體。此功能對使用的分配策略有特殊要求。僅策略aoff,aoffcbf,aoffcaobf,ageffcaoffm,ageffcbf和ageffcaobf支持廢棄的載體。
此功能還須要啓用多個線程特定的實例。啓用此功能時,若是還沒有啓用多個特定於線程的實例,則啓用該功能;若是當前策略不支持廢棄的載體,則啓用aoffcbf策略。能夠在全部基於alloc_util框架的分配器上啓用此功能,但temp_alloc除外(這將毫無心義)。
+M<S>acfml <bytes>
放棄無載體最小限制。 有效的<bytes>是表示塊大小限制的正整數。 載體中最大的空閒塊必須至少爲字節大,以便放棄該載體。 默認值爲零,但未來能夠更改。
另請參閱acul。
+M<S>acnl <amount>
放棄載體數量限制。 有效的<amount>是一個正整數,表明每一個分配器實例的最大被放棄載體數。 默認值爲1000,實際上將禁用該限制,可是之後能夠更改。
另請參閱acul。
+M<S>as bf|aobf|aoff|aoffcbf|aoffcaobf|ageffcaoff|ageffcbf|ageffcaobf|gf|af
分配策略。 如下策略是有效的:
請參閱「 alloc_util框架」一節中的分配策略說明。
+M<S>asbcst <size>
絕對單個塊載體收縮閾值(以千字節爲單位)。 當縮小mseg_alloc單個塊載體中的某個塊時,若是未使用的內存量小於此閾值,則該載體保持不變,不然縮小該載體。 另請參見rsbcst。
+M<S>atags true|false
在每一個分配的塊中添加一個小標籤,其中包含有關其內容和分配人的基本信息。 使用儀器模塊檢查此信息。
啓用時,運行時開銷是每一個分配一個字。 未來可能會隨時更改。
對於binary_alloc和driver_alloc,默認值爲true;對於其餘分配器類型,默認值爲false。
+M<S>e true|false
啓用分配器<S>。
+M<S>lmbcs <size>
最大(mseg_alloc)多塊載體大小(以千字節爲單位)。 請參閱「 alloc_util框架」部分中有關如何肯定mseg_alloc多塊載體的大小的說明。 在32位Unix風格的操做系統上,此限制不能設置爲> 128 MB。
+M<S>mbcgs <ratio>
(mseg_alloc)多塊載體增加階段。 請參閱「 alloc_util框架」部分中有關如何肯定mseg_alloc多塊載體的大小的說明。
+M<S>mbsd <depth>
最大塊搜索深度。 僅當爲分配器<S>選擇了合適策略時,此標誌纔有效。 使用良好擬合策略時,會將空閒塊放置在單獨的空閒列表中。 每一個空閒列表都包含特定範圍內的大小塊。 最大塊搜索深度設置了在搜索知足請求的合適塊期間在自由列表中要檢查的最大塊數的限制。
+M<S>mmbcs <size>
主多塊載體大小。 設置分配器<S>的主多塊載體的大小。 主多塊載體經過sys_alloc分配,而且永不釋放。
+M<S>mmmbc <amount>
最大mseg_alloc多塊載體。 分配器<S>經過mseg_alloc分配的最大多塊載體數。 達到此限制後,將經過sys_alloc分配新的多塊載體。
+M<S>mmsbc <amount>
最大mseg_alloc單塊載體。 分配器<S>經過mseg_alloc分配的最大單塊載體數。 達到此限制後,將經過sys_alloc分配新的單塊載體。
+M<S>ramv <bool>
從新分配老是移動。 啓用後,從新分配操做或多或少會轉換爲分配,複製,自由序列。 這一般能夠減小內存碎片,但會下降性能。
+M<S>rmbcmt <ratio>
相對多塊載體移動閾值(以百分比爲單位)。 當縮小位於多塊載體中的塊時,若是返回的內存的大小與先前大小之比大於此閾值,則移動該塊,不然將在當前位置縮小該塊。
+M<S>rsbcmt <ratio>
相對單個塊載體移動閾值(以百分比爲單位)。 當位於單塊載體中的塊縮小到小於參數sbct的大小時,若是未使用內存的比率小於此閾值,則該塊在單塊載體中保持不變,不然將其移入多塊載體 。
+M<S>rsbcst <ratio>
相對單個塊載體收縮閾值(以百分比爲單位)。 當縮小mseg_alloc單個塊載體中的一個塊時,若是未使用內存的比率小於此閾值,則該載體將保持不變,不然該載體將被縮小。 另請參見asbcst。
+M<S>sbct <size>
單塊載體閾值(以千字節爲單位)。 大於此閾值的塊將放置在單塊載體中。 小於此閾值的塊將放置在多塊載體中。 在32位Unix風格的操做系統上,此閾值不能設置爲> 8 MB。
+M<S>smbcs <size>
最小(mseg_alloc)多塊載體大小(以千字節爲單位)。 請參閱「 alloc_util框架」部分中有關如何肯定mseg_alloc多塊載體的大小的說明。
+M<S>t true|false
分配器的多個線程特定實例。 此選項僅對具備SMP支持的運行時系統有效。 具備SMP支持的運行時系統上的默認行爲是NoSchedulers + 1實例。 每一個調度程序使用其本身的無鎖實例,其餘線程使用一個公共實例。
在ERTS 5.9以前,能夠配置比調度程序更少數量的線程特定實例。 可是,這再也不可能。
配置alloc_util的標誌
全部基於alloc_util的分配都會受到影響。
+Muycs <size>
sys_alloc載體大小。 經過sys_alloc分配的載體的大小是sys_alloc載體大小的倍數。 可是,對於主多塊載體和在內存不足期間分配的載體,狀況並不是如此。
+Mummc <amount>
最大mseg_alloc載體。 放置在單獨的內存段中的最大載體數。 達到此限制後,新的載體將放置在從sys_alloc檢索的內存中。
+Musac <bool>
容許sys_alloc載體。 默認爲true。 若是設置爲false,則分配器決不會使用alloc_util框架建立sys_alloc載體。
literal_alloc的特殊標誌
+MIscs <size in MB>
literal_alloc超級載體大小(以MB爲單位)。 在64位體系結構上爲Erlang代碼中的字面量保留的虛擬地址空間量。 默認爲1024(即1 GB),一般就足夠了。 該標誌在32位體系結構上被忽略。
儀表標誌
+M<S>atags
在每一個分配的塊中添加一個小標籤,其中包含有關其內容和分配人的基本信息。 請參閱+ M <S>標記以獲取更完整的描述。
+Mit X
保留以備未來使用。 不要使用此標誌。
注意:啓用模擬器檢測後,模擬器將使用更多內存,而且運行速度會更慢。
其餘標誌
+Mea min|max|r9c|r10b|r11b|config
選項:
min
禁用全部能夠禁用的分配器。
max
啓用全部分配器(默認)。
r9c | r10b | r11b
按照在相應的Erlang / OTP版本中配置的全部分配器進行配置。 這些將最終被刪除。
config
禁用使用erts_alloc_config(3)建立分配器配置時沒法啓用的功能。
注意:此選項僅在運行erts_alloc_config(3)時使用,而在使用建立的配置時不可用。
+Mlpm all|no
鎖定物理內存。 默認爲否,即沒有物理內存被鎖定。 若是設置爲all,則運行時系統進行的全部內存映射都將鎖定到物理內存中。 若是設置爲all,則若是不支持此功能,用戶沒有足夠的特權或者不容許用戶鎖定足夠的物理內存,則運行時系統將沒法啓動。 若是達到了用戶對鎖定內存量的限制,則運行時系統也會因內存不足而失敗。
筆記
此處僅提供了一些默認值。 有關當前使用的設置以及分配器的當前狀態的信息,請參見erlang:system_info(allocator)和erlang:system_info({allocator,Alloc})。
注意:
這些標誌大多數都高度依賴於實現,能夠更改或刪除而無需事先通知。
erts_alloc沒有義務嚴格使用已傳遞給它的設置(它甚至能夠忽略它們)。
erts_alloc_config(3)工具可用於幫助建立適用於有限數量的運行時場景的erts_alloc配置。
也能夠看看
erl(1), erlang(3), erts_alloc_config(3), instrument(3)