SpringBoot(Java)のヒープメモリとスレッドスタックの整理

調査した件の書き溜め。

SpringBoot(Java)のアプリケーションにおいて、ヒープメモリ以外でメモリを消費している要因としていくつか考えらるが、特にスレッドスタックが大きな要因である可能性が高い。

各スレッドは、スレッドスタックという独自のメモリ領域を持ち、このスタック領域はスレッドの実行コンテキストに関する情報、例えばメソッド呼び出しの履歴やローカル変数などを保持している。

もしアプリケーションが多数のスレッドを使用している場合、それぞれのスレッドが持つスタックのメモリ使用量が累計されることで、合計のメモリ使用量が大きくなる可能性がある。

特にThreadPoolTaskExecutorのようなスレッドプールを利用して非同期に多くのタスクを実行している場合、多くのスレッドが同時に動作しているとスレッドスタックの消費メモリは無視できない量になることが考えられる。

また、Javaプロセスのメモリ消費には、ヒープやスレッドスタックの他にもメタスペース、JITコンパイラのオプティマイゼーション情報、ネイティブライブラリや直接バッファなども影響するが、スレッド数が多い場合、スレッドスタックの影響は特に注目すべきポイント。

  • ヒープ: Javaのオブジェクトが実際に割り当てられる場所で、これをさらにYoung領域とOld領域に分けることができる。Young領域はさらにEden領域とSurvivor領域に分割されている

  • ノンヒープ: Javaのオブジェクト以外のメモリ使用のための領域で、メタスペースやコードキャッシュなどの領域を持っている。Java 8より前のバージョンでは、ノンヒープには永続世代も含まれていた。

  • スレッドスタック:各スレッドの実行スタックで、メソッド呼び出しやローカル変数の情報が格納されている。

最新はこっちで書いてます