この記事は、陳建宇氏が執筆したWeChatパブリックアカウント「私の脳は揚げ魚です」から転載したものです。この記事を転載する場合は、Nao Nao Jin Jian Yu Leの公開アカウントまでご連絡ください。 以前、クラスメイトから、あるサービスのコンテナがメモリ制限を超えたために再起動を続けているという話がありました。彼は、メモリ リークがあるかどうかを尋ね、問題を回避するためにそれを調べて解決するように依頼しました。 私たちはショックを受け、すぐに監視+警報システムとパフォーマンス分析をチェックしたところ、アプリケーション指標はまったく高くなく、漏れがあるようには見えませんでした。 いったい何が問題なのでしょうか?コンテナに入り、上位のシステムインジケーターをチェックしました。
オーバーヘッドはそれほどないように見えますが、Go プロセスは 1 つだけですか?それでおしまい? よく見てみると、クラスメイトがVSZがすごく高いと言っていて、あるクラウドのコンテナメモリインジケーターがVSZ値に意外に近かったそうです。そのため、VSZ が原因であると疑い、一定の相関関係があると感じました。 この推測は正しいでしょうか? 基礎 この記事では、主に Go プロセスの VSZ を分析して、なぜそれが「高い」のかを確認します。 最初のセクションは、前提となる補足知識であり、順番に読むことができます。 VSZとは VSZ は、プロセスが使用できる仮想メモリの合計サイズです。これには、スワップアウトされたメモリ (スワップ)、割り当てられたが未使用のメモリ、共有ライブラリからのメモリなど、プロセスがアクセスできるすべてのメモリが含まれます。 なぜ仮想メモリなのでしょうか? 先ほど、VSZ は実際にはプロセスの仮想メモリの合計サイズであることを学びました。 VSZ を理解するには、まず「なぜ仮想メモリが必要なのか」を理解する必要があります。 基本的に、システム内のプロセスは CPU とメイン メモリのリソースを他のプロセスと共有します。 したがって、現代のオペレーティング システムでは、複数のプロセスの使用が非常に一般的です。プロセスが多すぎて大量のメモリを必要とする場合、仮想メモリがないと物理メモリが不足し、一部のタスクが実行に失敗したり、非常に奇妙な現象が発生したりする可能性があります。 たとえば、あるプロセスが別のプロセスが使用しているメモリに誤って書き込むと、メモリが破損してしまうため、仮想メモリは非常に重要な媒体となります。 仮想メモリには何が含まれていますか? 仮想メモリは次のように分割されます。
各プロセスの仮想メモリは独立しており、内部構造は下図のようになります。 カーネル仮想メモリにはカーネル コードとデータ構造が含まれます。 カーネル仮想メモリ内の特定の領域は、すべてのプロセスで共有される物理ページにマップされるため、「カーネル仮想メモリ」には実際には「物理メモリ」が含まれており、両者の間にはマッピング関係があることがわかります。 アプリケーション シナリオでは、各プロセスはカーネル コードとグローバル データ構造も共有するため、すべてのプロセスの物理ページにマップされます。 仮想メモリの重要な機能 メモリをより効率的に管理し、エラーを減らすために、現代のシステムでは、今日の主役である仮想メモリ (VM) と呼ばれるメインメモリの抽象的な概念が提供されています。 仮想メモリは、ハードウェア例外、ハードウェア アドレス変換、メイン メモリ、ディスク ファイル、およびカーネル ソフトウェアが相互作用する場所です。各プロセスに大規模で一貫性のあるプライベートなアドレス空間を提供します。仮想メモリは、次の 3 つの重要な機能を提供します。 メイン メモリをディスク上に格納されたアドレス空間のキャッシュとして扱い、メイン メモリ内にアクティブな領域のみを保持し、必要に応じてディスクとメイン メモリ間でデータを転送します。このようにして、メインメモリを効率的に使用します。 各プロセスに一貫したアドレス空間を提供するため、メモリ管理が簡素化されます。 各プロセスのアドレス空間が他のプロセスによって破損されるのを防ぎます。 まとめ 上記とはかなり相違があるかもしれません。簡単に言えば、この記事では、次のような知識ポイントに焦点を当てます。
トラブルシューティング 基礎を理解した後、私たちは正式に問題のトラブルシューティングを開始しました。最初のステップは、ビジネス ロジックのない Go プログラムの初期 VSZ がどのようになるかを確認するためのテスト プログラムを作成することです。 テスト アプリケーションコード:
進行状況を確認します:
結果から判断すると、VSZは4297048K、つまり約4Gです。一見するとかなり怖いです。明らかにビジネスロジックはありませんが、なぜこんなに高いのでしょうか?本当に不思議ですね。 漏れがないか確認する 不明な場合は、まずruntime.MemStatsとpprofを調べて、アプリケーションにリークがあるかどうかを判断します。ただし、これはビジネス ロジックのないデモ プログラムであるため、アプリケーションとは直接関係がないことは確かです。
FAQへ それから、私の最初の反応は Go FAQ を調べることでした (以前に見たことがあり、覚えていたため)。質問は「なぜ Go プロセスはこれほど多くの仮想メモリを使用するのですか?」で、答えは次のとおりです。 Go メモリ アロケータは、割り当ての領域として仮想メモリの大きな領域を予約します。この仮想メモリは特定の Go プロセスに対してローカルです。予約によって他のプロセスのメモリが奪われることはありません。 Go プロセスに割り当てられた実際のメモリ量を確認するには、Unix top コマンドを使用し、RES (Linux) または RSIZE (macOS) 列を参照します。 この FAQ は 2012 年 10 月に提出されました。それ以降、何年にもわたってそれ以上の説明はありません。問題とフォーラムを調べたところ、解決済みの問題の一部はすべて FAQ を指していることがわかりました。これでは明らかに私の好奇心を満たすことができなかったので、私は中に何が入っているのか調べ続けました。 メモリマップを表示する 上の図では、プロセス仮想メモリには主にコード、データ、ヒープ、スタック セグメント、共有ライブラリが含まれることを説明しました。当初は、プロセスが何らかのメモリ マッピングを実行し、その結果、大量のメモリ領域が予約されたことが疑われます。これを確認するには、次のコマンドを使用してチェックします。
この部分では、主にmacOSのvmmapコマンドを使用してメモリマッピング状況を表示し、このプロセスのメモリマッピング状況を知ることができます。出力分析から、これらの関連する共有ライブラリが占めるスペースは大きくないことがわかります。 VSZ が高くなる根本的な原因は、共有ライブラリやバイナリ ファイルには存在しません。しかし、問題点である大量のメモリ空間を確保する動作は見られませんでした。 注: Linux システムの場合は、cat /proc/PID/maps または cat /proc/PID/smaps を使用して表示できます。 システムコールを表示する メモリ マップにメモリ領域を予約する明確な動作が見られないため、次のようにプロセスのシステム コールを調べて、メモリ操作の動作があるかどうかを確認します。
このセクションでは、macOS の dtruss コマンドを使用して、このプログラムの実行時に行われたすべてのシステム コールを監視および表示し、メモリ管理に関連するメソッドが次のとおりであることを発見しました。
ここでさらに疑わしいのは、dtruss の最終統計で 10 回以上呼び出される mmap メソッドです。 Go ランタイムでは多くの仮想メモリ要求が行われると考えられます。 読み進めて、どの段階で仮想メモリ領域が要求されるかを確認しましょう。 注: Linux を使用している場合は、strace コマンドを使用できます。 Go ランタイムを表示 プロセスを開始する 以上の分析により、Go プログラムの起動時に VSZ が低くなっていないことがわかり、共有ライブラリなどが原因ではなく、システムコールがプログラム起動時に mmap などのメソッドを呼び出していることが分かります。 すると、Go が初期化フェーズ中にこのメモリ領域を予約していると完全に推測できます。最初に行う必要があるのは、Go ブート プロセスをチェックして、それがどこに適用されているかを確認することです。 起動プロセスは次のとおりです。
注: @曹大の「Go プログラムの起動プロセス」と @全成の「Go プログラムの実行方法」を読むことをお勧めします。 動作環境を初期化する 明らかに、次のように実行時に schedinit メソッドを調べたいと思います。
使用の観点から見ると、mallocinit メソッドがメモリ アロケータを初期化することは明らかです。引き続き下を見ていきましょう。 メモリアロケータを初期化する マロシニット 次に、mallocinit メソッドを正式に分析します。ブート プロセスでは、mallocinit が主に Go プログラムのメモリ アロケータの初期化を担当します。今日は、主に仮想メモリアドレスを次のように分析します。
なぜ 32 ビット システムか 64 ビット システムかを判断する必要があるのかと尋ねる友人もいるかもしれません。これは、異なるビット番号の仮想メモリのアドレス指定範囲が異なるため、それらを区別する必要があり、そうしないと、高ビットの仮想メモリ マッピングの問題が発生するためです。予約スペースを申請する際には、arenaHints リスト内のノードであり、次の構造を持つ arenaHint 構造について言及することがよくあります。
では、ここで言及されているアリーナとは何でしょうか?これは実際には Go のメモリ管理の概念です。 Go ランタイムは、要求された仮想メモリを次のように 3 つの大きなブロックに分割します。 画像
ここでは、Go メモリ内の area 領域の役割を理解する必要があります。 mmap 上記の分析により、mallocinit の目的はすでにわかっていますが、前に見た mmap システム コールが mallocinit とどのような関係があり、どのように関連しているかについてはまだ混乱しているかもしれません。次に、次のような下位レベルのコードを見てみましょう。
Go ランタイムには、一連のシステムレベルのメモリ呼び出しメソッドがあります。この記事で取り上げる主なものは次のとおりです。
理にかなっているように思えますが、mallocinit メソッドが初期化されるとき、mmap メソッドはどこで関与するのでしょうか?以下のように、表面からは明らかではありません。
実際、mheap_.arenaHintAlloc.alloc() を呼び出すと、mheap の下の sysAlloc メソッドが呼び出され、sysAlloc は mmap メソッドとの呼び出し関係を持ちますが、このメソッドは次のように通常の sysAlloc とはまったく異なります。
mheap.sysAlloc が実際に sysReserve メソッドを呼び出していることに驚かれるかもしれません。sysReserve メソッドは、OS システムからメモリ アドレス空間を予約するための特定のメソッドです。驚きじゃないですか?すべてがつながっているようです。 まとめ このセクションでは、まずテスト プログラムを作成し、次に型破りなトラブルシューティングのアイデアに基づいて、疑わしい点を段階的に追跡しました。全体的なプロセスは次のとおりです。
結論から言うと、VSZ(プロセス仮想メモリサイズ)は共有ライブラリなどとはほとんど関係がありません。主にGoランタイムに直接関係しており、前の図に示したランタイムヒープ(malloc)に関係しています。 Go ランタイムに変換すると、メモリ アロケータ mallocinit の初期化フェーズ中に一定量の仮想空間が予約されます。 仮想メモリ空間の予約に何が影響するかは哲学的な問題です。ソースコードの観点から見ると、主なポイントは次のとおりです。
要約する Go がどこにあるのか、どのような要因がそれに影響を与えるのか、そして大量の仮想メモリ空間を予約するためにどのようなメソッドが呼び出されるのかを段階的に分析して説明しました。ただし、プロセス仮想メモリ (VSZ) の高さについては間違いなく心配することになります。何か問題はありますか?私の分析は次のとおりです。
考える Go VSZ が高くても大きな問題は発生しないので、ここでは一安心です。しかし、よく考えてみると、なぜ Go はこれほど多くの仮想メモリを必要とするのでしょうか? 全体的な考慮事項は次のとおりです。
参照する Golang による仮想メモリの割り当てが高い GOメモリ管理 GoBigVirtualSize Goプログラムメモリ使用 曹達の囲碁プログラムの起動プロセス Quan Cheng の Go プログラムはどのように実行されますか? Ou Shenのボンネットの下 |
>>: 5G をサポートするにはクラウドネイティブ エッジが本当に必要ですか?
友人のウェブサイトのキーワードランキングが変わっているのをよく見かけるので、その理由を探して、検索エ...
今朝、いつものように管理しているいくつかのウェブサイトを開いたところ、これらのウェブサイトのランキン...
現在、どの都市にもさまざまな規模の病院があり、ユーザーには多くの選択肢があります。この点だけから見て...
オンラインプロモーションは多くのレベルに分かれており、ウェブサイト最適化ランキングは最も一般的なウェ...
papashosting.com は新しく設立された会社のようです。ドメイン名登録、仮想ホスティング...
偶然、SEO業界に加わりました。しばらく勉強した後、SEO についてある程度理解するようになりました...
[はじめに] ユーザーのプライバシーを保護するために、直接消費者データを保有する Taobao など...
長い間、マーケティングに関する記事を書いていませんでした。今日は、eコマースサイトのシングルページマ...
社内でホームページについて、またそれを改善するための方法について議論し続けるなら、過去に思い描いてい...
月収10万元の起業の夢を実現するミニプログラム起業支援プラン多くの人が、ウェブサイトのタイトル変更に...
第4回決済ライセンス発行から1か月余り後、中国人民銀行は先日、非金融機関向けに第5回「決済業務ライセ...
Dogyun は 6 月 18 日に特別プロモーションを開始しました。13 のデータセンターはすべて...
SEO 最適化に関しては、業界のベテランであっても、この分野に参入したばかりの新人であっても、多かれ...
私は現在、RCNTEC株式会社に勤務しており、日々分散環境に取り組んでいます。 ISC BIND を...
一昨日、A5タスクエリアでタスクを見ました。ウェブサイトのインクルードが常に10未満で、何をしても無...