Skip to content

Low memory setup zh TW

ArchiBot edited this page Dec 19, 2022 · 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 設定(簡單)

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

  • 永遠不要執行多個ASF實例。 ASF可以同時處理無限個Bot,除非您需要將每個ASF實例連結至不同的介面/IP地址,否則您只應該擁有​一個​有多個Bot(如果需要)的ASF程序。
  • 善用​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永遠不會使用超出您實際承受範圍的記憶體的最佳方法,即使在高負載下,也能為您的設備提供一些喘息的空間,但同時仍然能使程式盡可能高效地完成工作。

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

This setting configures the memory threshold of your whole OS, which once passed, causes GC to become more aggressive and attempt to help the OS lower the memory load by running more intensive GC process and in result releasing more free memory back to the OS. It's a good idea to set this property to maximum amount of memory (as percentage) which you consider "critical" for your whole OS performance. Default is 90%, and usually you want to keep it in 80-97% range, as too low value will cause unnecessary aggression from the GC and performance degradation for no reason, while too high value will put unnecessary load on your OS, considering ASF could release some of its memory to help.

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

This is undocumented property that turned out to work exceptionally well for ASF, by limiting size of GC generations and in result make GC purge them more frequently and more aggressively. Default (balanced) latency level is 1, but you can use 0, which will tune for memory usage.

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

This offers little improvement, but may make GC even more aggressive when system will be low on memory, especially for ASF which makes use of threadpool tasks heavily.


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

# Don't forget to tune those if you're planning to make use of them
export DOTNET_GCHeapHardLimitPercent=0x4B # 75% as hex
export DOTNET_GCHighMemPercent=0x50 # 80% as hex

export DOTNET_GCLatencyLevel=0
export DOTNET_gcTrimCommitOnLowMemory=1

./ArchiSteamFarm # For OS-specific build
./ArchiSteamFarm.sh # For generic build

或在Windows(PowerShell)上:

# Don't forget to tune those if you're planning to make use of them
$Env:DOTNET_GCHeapHardLimitPercent=0x4B # 75% as hex
$Env:DOTNET_GCHighMemPercent=0x50 # 80% as hex

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

.\ArchiSteamFarm.exe # For OS-specific build
.\ArchiSteamFarm.cmd # For generic build

Especially GCLatencyLevel will come very useful as we verified that the runtime indeed optimizes code for memory and therefore drops average memory usage significantly, even with server GC. It's one of the best tricks that you can apply if you want to significantly lower ASF memory usage while not degrading performance too much with OptimizationMode.


ASF 調整(終極)

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

  • As a last resort, you can tune ASF for MinMemoryUsage through OptimizationMode global config property. Read carefully its purpose, as this is serious performance degradation for nearly no memory benefits. This is typically the last thing you want to do, long after you go through runtime tuning to ensure that you're forced to do this. Unless absolutely critical for your setup, we discourage using MinMemoryUsage, even in memory-constrained environments.

最佳化建議

  • Start from simple ASF setup tricks, perhaps you're just using your ASF in a wrong way such as starting the process several times for all of your bots, or keeping all of them active if you need just one or two to autostart.
  • If it's still not enough, enable all configuration properties listed above by setting appropriate DOTNET_ environment variables. Especially GCLatencyLevel offers significant runtime improvements for little cost on performance.
  • If even that didn't help, as a last resort enable MinMemoryUsage OptimizationMode. This forces ASF to execute almost everything in synchronous matter, making it work much slower but also not relying on thread pool to balance things out when it comes to parallel execution.

It's physically impossible to decrease memory even further, your ASF is already heavily degraded in terms of performance and you depleted all your possibilities, both code-wise and runtime-wise. Consider adding some extra memory for ASF to use, even 128 MB would make a great difference.

Clone this wiki locally