Upgrade to Pro — share decks privately, control downloads, hide ads and more …

メモリリークが発生した時にpprofを使用して原因特定した話

 メモリリークが発生した時にpprofを使用して原因特定した話

メモリリークが起きた時に活用できるGoのpprofでの調査を再現できるようにしている資料

Avatar for ZONO33LHD

ZONO33LHD

May 17, 2025
Tweet

Other Decks in Programming

Transcript

  1. Goの標準ライブラリに というプロファイリングツールが あります! net/http/pprof ©2025 Dr.’s Prime ,Inc. pprofとは(ざっくり) HTTP

    サーバー経由で使用される プロファイルの視覚化ツール まずメモリがどう使用されて制限 超過してしまったかのプロファイ ルを分析する必要があります。 こんな時どうする? - Go公式でpprofを見る
  2. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 func "/leak-test" "/debug" "Starting server on :8080" if ":8080" nil nil "Failed to start server: %v" func nil if nil "error initializing app: %v\n" _ if nil "error initializing auth client: %v\n" http leakTestHandler http pprof Index log err http err log err w http ResponseWriter r http Request ctx r app err firebase ctx err log err err app ctx err log err main HandleFunc HandleFunc Println ListenAndServe Fatalf leakTestHandler Context NewApp Fatalf Auth Fatalf () { . ( , ) . ( , . ) // Start the HTTP server . ( ) . ( , ); { . ( , ) } } ( . , . ) { . () , . ( , ) { . ( , ) } , . ( ) { . ( , ) := != * := := != = != ©2025 Dr.’s Prime ,Inc. 当時の状況再現 httpのハンドラーに pprof.Indexを渡すだけで プロファイルデータを取 得できます! leakTestHandler関数は 再現・検 証するためのテスト環 境 Firebase初期化時のメ モリリークを です。 こんな時どうする? - メモリリークを検証
  3. こんな時どうする? - メモリリークを検証 ©2025 Dr.’s Prime ,Inc. 1 2 -

    % go run main.go /05/13 :15:05 Starting server on :8080 > 2025 22 1. サーバー起動
  4. 1 2 3 4 5 6 7 8 9 10

    11 12 13 - % POST http://localhost:8080/leak-test -i OKHTTP/1.1 OK Date: Wed, May 07:49:43 GMT Content-Length: Content-Type: text/plain utf-8 OKHTTP/1.1 OK Date: Wed, May 07:49:43 GMT Content-Length: Content-Type: text/plain utf-8 > =0 <1000 ++ 200 14 2025 2 = 200 14 2025 2 = for do done (( ; ; )); ; ; ; # リクエスト1000件まで繰り返される i i i -X charset charset curl 2. 起動したサーバーに対してリクエストを流す こんな時どうする? - メモリリークを検証 ©2025 Dr.’s Prime ,Inc.
  5. ©2025 Dr.’s Prime ,Inc. こんな時どうする? - メモリリークを検証 1 2 3

    4 - % leak-test.prof http://localhost:8080/debug/pprof/heap % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 2271k --:--:-- --:--:-- --:--:-- 3196k > 100 6547 0 6547 0 0 0 curl -o 3. 計測されたメモリの使用状況を leak-test.profファイルに出力
  6. こんな時どうする? - メモリリークを検証 ©2025 Dr.’s Prime ,Inc. 1 2 3

    4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - % go tool pprof leak-test.prof File: main Type: inuse_space Time: -05-13 :18:22 JST Entering interactive mode type commands, options pprof Showing nodes accounting .50kB, % of .50kB total Showing nodes out of flat flat% sum% cum cum% 2052kB % % 2052kB % runtime.allocm .07kB % % .07kB % go.opentelemetry.io/otel/internal/global. *meter .Int64Counter .31kB % % .31kB % google.golang.org/protobuf/internal/filedesc. *File .initDecls inline .05kB % % .38kB % runtime.main .04kB % % .04kB % go.opentelemetry.io/otel/internal/global. *meter .Float64Histogram .02kB % % .02kB % regexp/syntax.appendRange % % .11kB % firebase.google.com/go/v4. *App .Auth % % .11kB % firebase.google.com/go/v4/auth.NewClient % % .03kB % firebase.google.com/go/v4/auth.newCryptoSigner inline % % .03kB % firebase.google.com/go/v4/auth.newIAMSigner pprof traces .Int64Counter File: main Type: inuse_space Time: -05-13 :18:22 JST ~~~~ 以下省略 ~~~~ > 2025 22 5218 100 5218 10 45 39.32 39.32 39.32 1117 21.41 60.73 1117 21.41 513 9.84 70.56 513 9.84 512 9.81 80.38 1537 29.46 512 9.81 90.19 512 9.81 512 9.81 100 512 9.81 0 0 100 1629 31.22 0 0 100 1629 31.22 0 0 100 605 11.59 0 0 100 605 11.59 2025 22 ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) ( ) "help" for "o" for for top top 4. 計測したプロ ファイルを確認 firebase.google.com /go/v4.(*App).Auth が1629kB使っている 事が分かります。これ はリクエスト回数を増 やすほどメモリ使用量 が増える ①実行コマンド ②topを実行
  7. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 func ctx context err error firebaseApp err firebase ctx nil err nil log err authClient err firebaseApp ctx err nil log err func http leakTestHandler http pprof Index log err http nil err nil log err func w http ResponseWriter r http Request w http StatusOK w init Background NewApp Fatalf Auth Fatalf main HandleFunc HandleFunc Println ListenAndServe Fatalf leakTestHandler WriteHeader Write byte () { // アプリケーション起動時に一度だけ初期化 . () , . ( , ) { . ( , ) } // Authクライアントを一度だけ初期化 , . ( ) { . ( , ) } } () { . ( , ) . ( , . ) // Start the HTTP server . ( ) . ( , ); { . ( , ) } } ( . , . ) { . ( . ) . ([] ( )) } := = != = != := != * var if "error initializing app: %v\n" if "error initializing auth client: %v\n" "/leak-test" "/debug" "Starting server on :8080" if ":8080" "Failed to start server: %v" "OK" こんな時どうする? - 修正コード 5. 修正コード 原因:Authクライアントを Requestの度に生成されてい た 修正方法:Authクライアン ト生成を1度のみにする 追加関数 ©2025 Dr.’s Prime ,Inc.
  8. こんな時どうする? - 修正後の再検証 ©2025 Dr.’s Prime ,Inc. 1 2 3

    4 5 6 7 8 9 10 11 12 13 14 15 % - 2571 100% 2571 10 26 % % % 39.89% 39.89% 39.89% 517 20.10% 60.00% 517 20.10% / / / * 516 20.09% 80.09% 516 20.09% 512 19.91% 100% 512 19.91% / / - - / / / / 0 0% 100% 517 20.10% / / - - / 0 0% 100% 517 20.10% / / - - / 0 0 0% 100% 517 20.10% / / / * 0 0% 100% 517 20.10% / / / * 0 0% 100% 517 20.10% / / / 0 0% 100% 517 20.10% / / / go tool pprof leak test pprof top Showing nodes accounting 76kB 76kB total Showing top nodes out flat flat sum cum cum 1026kB 1026kB runtime allocm 02kB 02kB google golang org protobuf internal strs Builder inline 64kB 64kB runtime procresize 10kB 10kB github com envoyproxy go control plane envoy config tap v3 init 02kB github com envoyproxy protoc gen validate validate file_validate_validate_proto_init 02kB github com envoyproxy protoc gen validate validate init 02kB google golang org protobuf internal filedesc Extension unmarshalSeed 02kB google golang org protobuf internal filedesc File unmarshalSeed 02kB google golang org protobuf internal filedesc Builder Build 02kB google golang org protobuf internal filedesc inline . ( ) . , . . . . . . .( ). ( ) . . . . . . . . . . . . . . . . . . ( ). . . . . ( ). . . . . . . . . . ( ) prof grow makeFullName for of of 5. 修正コードでの再検証
  9. こんな時どうする? - 修正後のグラフ ©2025 Dr.’s Prime ,Inc. やったね!! 9% 6%

    GCによる解放 メモリの使用量が10%以下で安定していることがわかる
  10. ©2025 Dr.’s Prime ,Inc. 採用情報 ©2025 Dr.’s Prime ,Inc. ぜひドクターズプライムの魅力を覗きにきてください!

    下の3つから、あなたのアクションをお選びください!!よろしくお願いします アクション1 オフィスに遊びにいく! 社内外の交流会を開催しています。 毎週火曜・金曜 19:30~ 入退場自由・無料です。 申し込み方法 ・右のQRコードから応募 ・note「社内外交流会〜ピザパーティー〜を開催しています! 」 もしくは アクション3 入社ブログを読んでみる! 会社HPの「働くひとたち」から  入社ブログをぜひご覧ください。 株式会社ドクターズプライム | 働く人たち 株式会社ドクターズプライムの メン バー 紹介ペー ジ... drs prime.com htt ps ://drs prime.com /mem ber まわりの友人に もシ ェア あなたの シェアが、命を 救う アクション 2 カジュア ル面談を 受ける! 選 考を 進ま れる前にご希望ございましたら、 カジュア ル面談を 実施してお りま す! 申し込み方法 ・ 採用情報ペー ジの 「 話を 聞く」から Careers | Dr.'s Prime 株式会社ドクターズプライムの 採用関連情報ペー ジ... c areers. drs prime.com htt ps ://drs prime.com /recr uit /