web-dev-qa-db-ja.com

デフォルトのスタックサイズは何ですか、成長できますか?ガベージコレクションでどのように機能しますか?

各スレッドには独自のstackがあることを理解しています。プリミティブ型と参照はスタックに保持され、オブジェクトはスタックに保持されません。

私の質問は:

  • スタックはどれくらい成長できますか? (パラメーター-Xmsおよび-Xmxと同様)
  • その成長を制限できますか?
  • スタックにはデフォルトの最小値と最大値がありますか?
  • スタックでガベージコレクションはどのように機能しますか?
66
Batty

スタックはどれくらい成長できますか?

VMという名前のssという名前のオプションを使用して、最大スタックサイズを調整できます。 VMオプションは通常、-X {option}を使用して渡されます。したがって、Java -Xss1Mを使用して、スタックサイズの最大値を1Mに設定できます。

各スレッドには少なくとも1つのスタックがあります。一部のJava Virtual Machines(JVM)は、Java stack(Javaメソッド呼び出し)およびnative stack(VMのネイティブメソッド呼び出し)を1つのスタックに入れ、Managed to Nativeを使用してスタックのアンワインドを実行しますM2NFrameとして知られるフレーム。一部のJVMは、2つのスタックを別々に保持します。 Xssは、ほとんどの場合、Java St​​ackのサイズを設定します。

多くのJVMでは、異なるプラットフォームのスタックサイズに異なるデフォルト値を設定します。

この成長を制限できますか?

メソッド呼び出しが発生すると、そのスレッドのスタック上に新しいスタックフレームが作成されます。スタックには、ローカル変数、パラメーター、戻りアドレスなどが含まれます。Javaでは、オブジェクトをスタックに配置することはできません。オブジェクト参照のみをスタックに格納できます。配列はJavaのオブジェクトでもあるため、配列もスタックに格納されません。したがって、ローカルプリミティブ変数、パラメーターをオブジェクトにグループ化してそれらの量を減らすと、スタック上のスペースを減らすことができます。実際、オブジェクトをJavaスタックに配置できないという事実は、パフォーマンスにある程度影響します(キャッシュミス)。

スタックにはデフォルトの最小値またはデフォルトの最大値がありますか?

前にも言ったように、VMはそれぞれ異なり、バージョンによって変わる可能性があります。 here を参照してください。

ガベージコレクションはスタックでどのように機能しますか?

Javaのガベージコレクションはホットトピックです。ガベージコレクションは、ヒープ内の到達不能オブジェクトを収集することを目的としています。そのためには、「到達可能」の定義が必要です。スタック上のすべては、GCのルートセット参照の一部を構成します。すべてのスレッドのすべてのスタックから到達可能なものはすべて、ライブと見なされる必要があります。 Threadオブジェクトや一部のクラスオブジェクトなど、他のルートセット参照がいくつかあります。

これは、GCでのスタックの非常に曖昧な使用にすぎません。現在、ほとんどのJVMは世代別GCを使用しています。 この記事 は、Java GCについて簡単に紹介しています。そして最近、私は 非常に良い記事 を読みました。 Oracle jvmのGCは非常に似ているので、それも役立つと思います。

78
StarPinkER

あなたが言うように、ローカル変数と参照はスタックに保存されます。メソッドが戻ると、スタックポインタはメソッドが開始される前の位置に単純に戻ります。つまり、すべてのローカルデータが「スタックから削除されます」。したがって、スタックで発生するガベージコレクションはなく、ヒープでのみ発生します。

特定の質問に答えるには:

  • スタックサイズを増やす方法については、 この質問 を参照してください。
  • 次の方法でスタックの増加を制限できます。
    • オブジェクト内の多くのローカル変数のグループ化:そのオブジェクトはヒープに格納され、参照のみがスタックに格納されます
    • ネストされた関数呼び出しの数を制限します(通常、再帰を使用しないことにより)
  • Windowsの場合、デフォルトのスタックサイズは32ビットで320k、64ビットで1024kです。 このリンク を参照してください。
12