Go 1.3 ガベージ コレクターによるサーバー メモリの保持
問題の理解
不規則なトラフィックによる接続を処理する TCP サーバーが大量のシステム メモリを使用しているそれはオペレーティング システムにリリースされません。同じマシン上で複数のサーバーを実行している場合、時間の経過とともにメモリ リソースが枯渇する可能性があるため、この動作は問題になります。
バックグラウンド
Go のガベージ コレクター (GC) は未使用のヒープ メモリを解放しますが、解放されません。プロセスの仮想アドレス空間は常に縮小されません。 Windows プラットフォームでは、これは不可能です。 Unix ベースのシステムでも、Go はシステム コールを使用して、未使用のヒープ メモリを再利用できることを OS に通知しますが、これには時間がかかります (最大 7 分)。
分析
に基づくGo コミュニティ フォーラムから収集された情報によると、問題は次の要因に関連している可能性があります:
-
Go がリリースされないすべてのメモリを OS に転送します: Go はヒープ変数のみを解放します。 goroutine スタックは解放されません。
-
遅延メモリ解放: メモリは、GC によって空きとしてマークされた後、すぐに OS に返されない場合があります。 OS スイープも必要で、これには最大 7 分かかる場合があります。
-
過剰に報告されたメモリ使用量: 割り当てられたすべてのメモリが「実」メモリであるわけではありません。一部はランタイムによって使用される可能性がありますが、プログラムでは使用されず、OS が処理します。
潜在的な解決策
-
明示的メモリ解放: 強制ガベージruntime.GC() を使用してコレクションを実行し、次を使用してメモリを OS に明示的に解放します。 runtime.FreeOSMemory.
制限事項
- runtime.GC() は、パフォーマンスに影響を与える可能性があるため、慎重に使用する必要があります。
- runtime.FreeOSMemory のみが機能します。 GC が実行されている場合。
- Goroutine のスタック メモリは使用されません。
謝辞
- Dmitri Vyukov (Go 開発者) がこの問題に関する重要な洞察を提供してくれました。
以上がGo 1.3 サーバーがメモリを OS に解放しないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。