階段の謎-ステップ プロファイル。私たちのRustイニシアチブの中で、axum キャリア、メモリ使用に関していくつかのなじみのない習慣が存在します。 なじみのない色目を持つメモリ プロファイルを持つことは、私が Rust プログラムに要求する最後のことですが、それでもここにあります.
キャリアは、一定時間「フラット」なメモリで突進し、その後、元のプラトーにジャンプします。 このサンプルは何時間にもわたって繰り返されますが、負荷がかかることはめったにありませんが、現在は継続的ではありません。 思いやりのある部分は、明るく長くなるのを見るとすぐに、記憶が下に降りてくることはめったにありませんでした。 以前は、メモリが置き忘れられたり、まれに「リーク」されたりしていたかのようでした.
同じ古い条件下では、この「階段状」プロファイルは色目があることにまったく慣れていませんが、あるレベルでは、メモリ使用率が不釣り合いに上昇しました。 無制限のメモリ スコークにより、サービスが終了せざるを得なくなる可能性があります。 サービスが終了すると、可用性が低下する可能性があります… これは
業界にとって悪いことです 。
全体的に、プログラムで驚くべきメモリ スコークを想像するときは、リークを想像します。 無音、これは多様に見えた。 リークがあると、非常に規則的で奇妙な、スコークのサンプルを見る傾向があります。
掘り下げていきます
2つの切実な質問がありました:
古代の測定基準で色相を調べると、同じパターンの明るい光が、一定の間隔が長くなりましたが、これまでのどの方法でも、このスコークの発生を含めることはできませんでした。 (「階段状」のサンプルが同じ古い
私たちにとって)、この習慣を再現するための正当な技術が欲しいです.
できればおそらく、それ自体を表現するための「ステップ」に力を入れてから、記憶の鳴き声を抑えるための選択ステップを行うときに、別の習慣をテストするテクニックを構成します. 私はまた、私たちの git 古代の前に後退し、キャリアが存在しないと言われている限りないスコークが存在しなかったときに、ある程度時間を過ごすために住んでいました.
The負荷テストを実行するときに苦手なディメンションは次のとおりでした:
運送業者に発送された弊社本体の寸法です。
私にとっての魔法の組み合わせは: および
同時実行数の増加 .
ローカル ガジェットで負荷テストを実行する場合、あらゆる種類の制限要素が存在します。クライアントとサーバー自体の両方を動作させるために手元にあるプロセッサの有限オプションの側面。 音のない、私は私のローカル マシンのメモリ内の「階段」の外観を構成するために住んでいました。
マウントされたサイズのペイロードを利用し、リクエストをバッチで送信し、その間に一時的な余暇を挟んで、キャリアのメモリを一貫して1ステップずつドライブするために常駐していました.
私は、時間の経過とともにメモリを増やすことができる可能性がある一方で、間接的にある程度の収穫逓減を達成することを刺激するすべての方法を手に入れました. 最終的には、スコークの上限がいくらか (予想よりも大幅に増加した) ことになります。 楽しみながら、さまざまなペイロード サイズのリクエストを送信することで、上限をさらに引き上げることができる可能性があるすべての方法にたどり着きました。私は自分のインプットを特定していたので、以前の git をさかのぼって仕事をしていましたが、私たちの製造業の恐怖が今ではほとんどの伝統的な変更の影響ではないことを間接的に研究していました.
この「階段」をトリガーするワークロードの詳細は、ユーティリティ自体に固有のものですが、以前は おもちゃプロジェクト.
構造体 { ペイロード: serde_json:: 価格, } struct
WidgetCreateResponse { ID: 弦、
寸法: usize, } 非同期 fn create_widget(Json(ウィジェット): Json )<ウィジェット ) -> 応答 ( StatusCode:: 作成した, Json(プロセスウィジェット(ウィジェット
。クローン()まで起きていてください ) .into_response[emphasize] () }
process_widget( ) -> WidgetCreateResponse { ); widget_id Uuid:: new_v4( . ) させてto_vec(&ウィジェット.ペイロード); tokio:: time[emphasize] :: .unwrap_or_default(
寝る長さ:: from_millis( ) env ("SLEEP_MS" .as_deref () .unwrap_or(「150」
) .パース() , "無効な SLEEP_MS") ; WidgetCreateResponse .to_string() 次元 : バイト .レン(
} } widget_id ) . 起きていて 時間::そこから導き出すのに特別なことは必要ないことがわかりました。 axum
JSON ボディを受け取る単一のハンドラーを持つアプリ
私のおもちゃのプロジェクトでは記憶力が向上しますが、私たちが見たほど劇的ではありませんでした製造キャリア、それは私の調査の次のセクションを通してすべての方法をレビューし、区別するのをサポートするのに十分でした. また、多様なワークロードを試しながら、小さなコードベースのよりタイトな反復ループを構成するのにも役立ちました。 詳細については、
README を検索してください。どのように負荷テストを実行したか
バグ レビューや議論のためにフェッチを調達するのに時間を費やしましたが、これらはおそらく同じ習慣を描写している可能性があります。 一貫して出てきた用語は、ヒープの断片化
でした。 そして、この主題についてかなり勉強した後、それはおそらく私が何に合うかもしれないという影響を与えました
![]()
ヒープフラグメンテーションとは?
明らかな年齢の他の人々は、
デフラグユーティリティを見る能力を持っている可能性があります DOS または Dwelling Windows では、現在は容易ではないディスク上でブロックを転送して、「脆弱な」領域と「空き」領域を統合します。
ケース内 この老朽化した PC のドライブは容易ではなく、さまざまなサイズのファイルがディスクに書き込まれ、後で移動または削除されたため、他の脆弱な領域の間に手元のコンドミニアムの「穴」が残りました。 ディスクが構成され始めると、比較的小さな領域に収まらない元のファイルを作成しようとする可能性があります。 ヒープの断片化作業では、割り当ての失敗につながる可能性がありますが、ディスクの断片化の失敗モードはそれほど劇的ではない可能性があります。 ディスク上では、ファイルは常にサイレントである必要があり、小さなチャンクに分割されます。これにより、エントリが著しく、大気に適したものではなくなります (感謝 wongarsu
)訂正のため)。 ディスクドライブに対する応答は、これらの開始ブロックを実空間で再配置するために公開されているドライブを「デフラグ」(デフラグ)することです。
occur
できるのは、アロケータ (責任のあるオブジェクトプログラムへのメモリ割り当てを管理するため) 一定の時間間隔でさまざまなサイズの値を追加および削除します。 ギャップが小さすぎて散らばり、ヒープを介して元の「新しい」メモリブロックが分配され、他の方法では収まらない元の価格に対応する可能性があります。 悲しいことに、メモリ管理がどのように機能するかに起因しますが、「デフラグ」は、あなたが想像しなければならないことではありません.
もの:
serde
による JSON 解析、フレームワーク度に関する 1 つのことaxum、tokio、さらには特定のガジェットのブーム アロケータ実装の癖を完璧にします。 ルート トリガーをアピールしなくても (これらのいずれかが存在する場合)、習慣は私たちの環境で観察可能であり、必要最小限のアプリで批判的に再現可能です。
Ifこれが配列メモリに発生していたことですが、それについて何が達成されるように思われますか? 断片化を回避するためにワークロードを交互に切り替えることはおそらく容易ではないと思われます。 また、断片化の機会がどのように発生しているかについて、おそらくコード内にルート トリガーを蓄積するために、プロジェクト内のすべての依存関係を巻き戻すのは難しいようです。 では、何が実現すると思われるのでしょうか?
ジェマロック
を助けにjemalloc は "[emphasize] 断片化の回避とスケーラブルな並行性の強化。"
並行性は実際、私のプログラムの難しさの一部であり、断片化を回避することが重要でした。
jemalloc は、私が必要としている完璧なものを好むようです.
以来 jemalloc は、存在する原則内の断片化を回避するためにその技術を利用するアロケーターです。私たちのキャリアであった希望は、メモリを徐々に増加させることなく、より長くダートするために存在するようです.
私のプログラムへの入力、またはユーティリティの依存関係の山を交互にすることは、今ではそれほど簡単ではありません。 繰り返しになりますが、アロケーターを交換するのは簡単です。
readme、runt、またはテストドライブ用に決定するための作業は必要ありませんでした.私の
おもちゃプロジェクトのために、オプションで jemalloc のデフォルトのアロケーターを交換するためのカーゴ機能を追加しました そして負荷テストを再実行しました.