Skip to content

Low memory setup zh TW

ArchiBot edited this page Jan 26, 2024 · 45 revisions

低記憶體設定

這與​高效能設定​完全相反,若您想減少ASF的記憶體使用量,請遵照下列指示。這可能會降低效能。


依據定義,ASF在資源上屬於極輕量級。取決於您的使用情形,即使是128 MB的Linux VPS也可以執行它,儘管不建議使用那麼低的資源配置,因為這可能會導致各種問題。 在輕量化的同時,如果ASF需要更多記憶體才能以最佳速度執行,它也不會吝嗇於向作業系統請求更多的記憶體空間。

作為一個應用程式,ASF試圖盡可能最佳化與高效能,這也考慮了執行期間所使用的資源。 在記憶體方面,ASF更看重效能而不是記憶體使用量,這可能會導致記憶體臨時「尖峰」,例如,您可以注意到,當ASF從3頁或以上徽章頁面的帳號中提取並剖析第一頁,從中讀取總頁數,然後為每個額外頁面啟動提取工作,這會導致並行提取及剖析剩餘的頁面。 這種「額外」的記憶體使用量(與運算的最低限度相比)可以顯著增加執行速度與整體效能,以增加記憶體使用量為代價,平行執行所有工作。 類似的事情也發生於所有可以平行執行的一般ASF工作上,例如剖析交易提案,ASF可以一次剖析所有工作,因為它們都是相互獨立的。 最重要的是,ASF(C#執行環境)​不會​在之後立刻將未使用到的記憶體還給作業系統,您可以很快注意到ASF程序只會佔用越來越多的記憶體,但(幾乎)永遠不會將那些記憶體還給作業系統。 一些人可能已覺得這樣有問題,甚至可能懷疑產生了記憶體洩漏,但不用擔心,一切都在預料之中。

ASF經過非常好的最佳化,並會盡可能利用可以使用的資源。 ASF的高記憶體使用量不代表ASF主動​使用​這些記憶體,或​需要它們​。 通常ASF會保留分配的記憶體來作為未來行動的「空間」,因為如果我們在每次使用記憶體區塊時,都不需要向作業系統發出詢問,就可以大大地提高效能。 執行環境會在作業系統​真正​需要記憶體時,將ASF未使用的記憶體自動釋放回作業系統。 不使用的記憶體,就是被浪費掉的記憶體​。 當您​需要​的記憶體大於可用的記憶體時,您可能會遇到問題,但這並不是因為ASF保留了一些額外分配的記憶體以加速稍後執行的功能。 當您的Linux核心由於OOM(記憶體不足)而結束ASF程序時才會遇到問題,而不是您在​htop​看到ASF程序是記憶體使用量大戶時。

ASF使用的​垃圾回收​程序是種非常複雜的機制,它足夠智慧,不只可以考慮ASF自身,也可以考慮到作業系統及其他程序。 當您擁有大量的空閒記憶體時,ASF將會要求任何能夠提高效能的資源。 這甚至能夠達到1GB(使用伺服器GC時)。 在您作業系統的記憶體接近用滿時,ASF將會自動將其部分記憶體釋放回作業系統,以助系統穩定,此時ASF的記憶體使用量可以低至50MB。 50MB與1GB間的差異巨大,但在小型的512 MB VPS與32 GB的大型專用伺服器間的差異也是如此。 若ASF能保證這些記憶體能夠發揮作用,且同時沒有其他程序需要它們,ASF會更願意保留這些記憶體,並依據過去執行的常式進行自我最佳化。 ASF使用的GC是自調諧的,程序執行時間越長,效果就越好。

這也是ASF程序的記憶體使用量因設定而異的原因,因為ASF會竭盡所能地以​最高效率的方式​使用可用資源,而不是像Windows XP時代一樣,使用固定的資源。 ASF的實際(真實)記憶體使用量可以透過​stats指令​查看。若Bot不多,通常只會使用4 MB左右,若您啟用​IPC​或其他進階功能,則可能高達至30 MB。 請注意,​stats​指令回傳的記憶體數值包含尚未被垃圾回收的閒置記憶體。 剩下的都是共用執行環境記憶體(約40~50 MB)和執行的空間(因人而異)。 這同樣也是為什麼同一個ASF能在低記憶體VPS環境中只使用50 MB,而在您的桌面環境能最大使用到1 GB的原因。 ASF會主動適應您的環境,並會嘗試找到最佳平衡,使您在擁有大量的空閒記憶體可供使用時,既不帶給您的作業系統壓力,也不會限制到自身的效能。


當然,有很多方式可以幫助您,在您所期望的ASF記憶體使用方面指出正確的方向。 在一般情形下,若您不需要這樣做,就最好讓垃圾回收程序依照它所認為最好的方式去運作。 但這並不總是可行的,例如如果您的Linux伺服器還同時代管了多個網站、MySQL資料庫與PHP worker,那麼當您接近OOM時,您會無法承擔ASF自行回收的結果,因為通常發生的太晚,且效能下降會非常快。 此時您可能會對進一步調整感到興趣,並因而來閱讀本頁面。

以下建議分為數類,其難度各不相同。


ASF 設定(簡單)

下列技巧​不會對效能產生負面影響​,可以在所有設定下放心使用。

  • 如果可以的話,執行​Generic版本​的ASF。 Generic版本的ASF使用較少的記憶體,因為它並未內建執行環境,沒有以單獨的檔案型式來提供,也就不需要在執行時自我解壓縮。因此檔案更小,且對記憶體的使用也較少。 適用於特定作業系統的套件則更加簡單易用,但它們也一併附隨了執行ASF所需的一切資源,而若您使用了Generic版本的ASF,就能夠自行管理這些資源。
  • 永遠不要執行多個ASF實例。 ASF可以同時處理無限個Bot,除非您需要將每個ASF實例連結至不同的介面/IP地址,否則您只應該擁有​一個​有多個Bot(如果需要)的ASF程序。
  • 善用Bot設定​FarmingPreferences​中的​ShutdownOnFarmingFinished​。 啟用狀態的Bot比未啟用的還要消耗更多資源。 這裡的節省不明顯,因為需保留Bot的狀態,但仍可以節省些許資源,特別是與網路相關的資源,例如TCP Socket。 如果需要,您可以隨時調出其他Bot。
  • 不要擁有過多的Bot。 非​Enabled​的Bot實例消耗較少資源,因為ASF不會啟動它。 也請注意,ASF會對您的每個設定檔建立一個Bot,因此若您不需要​start​指定的Bot,且希望節省一些額外的記憶體空間,您可以暫時將​Bot.json​重新命名成例如​Bot.json.bak​的名稱,以避免ASF為被您停用的Bot實例建立狀態。 若不將它重新命名回去,您將會無法​start​它,且ASF也不會在記憶體中保留這個Bot的狀態,能為其他東西留出空間(只節省非常少的空間,在99.9%的情形下您無需這麼做,將您Bot的​Enabled​設定成​false​就已經夠了)。
  • 妥善調整設定檔。 特別是ASF全域設定中有很多變數可以調整,例如增加​LoginLimiterDelay​能使您Bot的啟動速度減慢,使已經啟動的實例能夠同時提取徽章頁面;如果是減少此值,就會使您的Bot盡快全數啟動,這將會消耗更多資源,因為更多Bot將同時執行主要工作(例如剖析徽章頁面)。 必須同時完成的工作越少⸺使用的記憶體就越少。

這些都是您在處理記憶體使用量相關問題時可以考慮的幾件事情。 但是,這些事都不是影響記憶體使用量的「關鍵點」,因為記憶體的使用主要來自ASF必須處理的事情上,而不是來自掛卡的內部結構。

消耗資源最多的功能是:

  • 徽章頁面剖析
  • 物品庫剖析

這代表ASF在讀取徽章頁面及處理物品庫(例如發送交易提案,或STM相關操作)時,記憶體使用量將會達到峰值。 這是因為ASF必須處理非常大量的資料⸺您直接使用瀏覽器開啟這兩個頁面時的記憶體使用量也不會比這個低多少。 很抱歉,但它就是這麼運作的⸺減少您的徽章頁面數量,或將您的物品庫物品維持在較少的數量,都會對此有所幫助。


執行環境調整(進階)

下列技巧​涉及效能的下降​,應謹慎使用。

套用這些設定的建議方法,是設定​DOTNET_​環境屬性。 當然,您也可以使用其他方法,例如​runtimeconfig.json​,但有些設定無法如此設定。除此之外,ASF會在每次更新時,將您的自訂​runtimeconfig.json​取代成自己的檔案,因此,我們建議使用環境屬性,這樣您在啟動程序前就可以輕鬆設定。

.NET執行環境使您能夠以多種方法​調整垃圾回收​,依據您的需求高效微調垃圾回收(GC)程序。 我們記錄了下列我們認為特別重要的屬性。

指定允許的GC堆積使用量,以總實體記憶體的百分比表示。

ASF程序的「硬性」記憶體限制,本設定會將GC調整為只使用總記憶體的一部分而不是全部。 在使用各式伺服器的情形下,本設定可能會特別有用。您可以為ASF設定專屬的固定百分比的伺服器記憶體,使ASF無法使用超過此數值。 請注意,限制ASF能夠使用的記憶體並不會使這些必需分配的記憶體神奇地消失,因此,如果將此值設定得過低,就可能會出現記憶體不足的情形,ASF程序將會被強制終止。

反之,將此值設定得夠高,是確保ASF永遠不會使用超出您實際承受範圍的記憶體的最佳方法,即使在高負載下,也能為您的設備提供一些喘息的空間,但同時仍然能使程式盡可能高效地完成工作。

設定垃圾回收程序以節省記憶體,但會使垃圾回收機制更加頻繁,且可能導致更長的暫停時間。

接受0~9的值。 擁有越高的數值,GC更會偏向最佳化記憶體而非效能。

指定在GC變得更積極後的記憶體使用量。

本設定是設定整個作業系統的記憶體閾值,一旦超過,GC將會變得更加積極,並嘗試透過執行更密集的GC程序來幫助作業系統降低記憶體負荷,來將更多的閒置記憶體釋放給作業系統。 最好將本屬性設定成您認為整個作業系統「臨界」效能的最大記憶體使用量(百分率)。 預設值為90%,通常您希望將它維持在80~97%的範圍內,因為太低的值會使GC產生不必要的積極並使效能無故下降,而太高的值會給您的作業系統帶來不必要的負載,應該讓ASF釋放一些記憶體來緩解。

指定您要最佳化的GC延遲層級。

這是一個未記錄的屬性,證明對ASF非常有效,透過限制GC產生的大小,來使GC更頻繁、更積極地清除它們。 預設值(平衡)為​1​,但您可以使用​0​,這將會針對記憶體使用量來進行調整。

設定後,我們會更積極為臨時段修整提交的空間。 這可用於執行多個伺服器程序實例,它們希望在這些實例中盡可能不要提交記憶體。

這幾乎無法改善,但當系統記憶體不足時,可能會使GC變得更加積極,特別是對於大量使用執行緒集區工作的ASF來說。


您可以透過設定適當的環境變數來啟用所選的屬性。 舉例來說,在Linux(Shell)上:

# 若您打算使用它們,別忘了調整一下
export DOTNET_GCHeapHardLimitPercent=0x4B # 75% 的十六進位
export DOTNET_GCHighMemPercent=0x50 # 80% 的十六進位

export DOTNET_GCConserveMemory=9
export DOTNET_GCLatencyLevel=0
export DOTNET_gcTrimCommitOnLowMemory=1

./ArchiSteamFarm # 用於特定作業系統的組建版本
./ArchiSteamFarm.sh # 用於 Generic 組建版本

或在Windows(PowerShell)上:

# 若您打算使用它們,別忘了調整一下
$Env:DOTNET_GCHeapHardLimitPercent=0x4B # 75% 的十六進位
$Env:DOTNET_GCHighMemPercent=0x50 # 80% 的十六進位

$Env:DOTNET_GCConserveMemory=9
$Env:DOTNET_GCLatencyLevel=0
$Env:DOTNET_gcTrimCommitOnLowMemory=1

.\ArchiSteamFarm.exe # 用於特定作業系統的組建版本
.\ArchiSteamFarm.cmd # 用於 Generic 組建版本

特別是​GCLatencyLevel​非常有用,我們驗證了執行環境確實能最佳化記憶體中的程式碼,因此即使使用伺服器GC,也能顯著降低了平均記憶體使用量。 若您希望使用​OptimizationMode​顯著降低ASF記憶體使用量的同時又不會過多降低效能,那麼這是您可以使用的最佳技巧之一。


ASF 調整(終極)

下列技巧​涉及效能的嚴重下降​,應謹慎使用。

  • 作為最後的手段,您可以透過​OptimizationMode全域設定屬性​來調整ASF。 請仔細閱讀它的作用,因為會使效能嚴重下降,且幾乎沒有記憶體方面的改進。 這通常是​您最不想做的事​,確保只有在您​執行環境調整​之後才被迫這樣做。 除非對您的設定至關重要,否則我們不建議使用​MinMemoryUsage​,即使在記憶體受限制的環境中也是如此。

最佳化建議

  • 從簡單的ASF設定方式開始,使用​Generic版本的ASF​,並檢查您是否正以錯誤的方式使用著ASF,例如:為您所有的Bot重複啟動程序,或在您只需要一或兩個Bot自動啟動的情形下讓所有的Bot都自動啟動了。
  • 若仍然不夠,請透過設定適當的​DOTNET_​環境變數來啟用上述的所有設定屬性。 特別是​GCLatencyLevel​能在只犧牲極小效能的情形下明顯改善執行環境。
  • 若仍沒有幫助,作為最後的手段,啟用​OptimizationMode​的​MinMemoryUsage​。 這會強迫ASF同步執行幾乎所有東西,使它的運作速度變慢許多,且在平行執行時也不再依賴執行緒集區來平衡。

在物理上已無法進一步減少記憶體使用量,您的ASF的效能已經嚴重退化,且不論是程式碼或執行環境方面,您都已耗盡了所有的可能性。 請考慮加入一些額外的記憶體來提供ASF使用,即使只有128 MB,也會有很大的不同。

Clone this wiki locally