Java 仮想マシン仕様によれば、プログラム カウンタに加えて、仮想マシン メモリの他のいくつかのランタイム領域でも OutOfMemoryError (以下、OOM) 例外が発生する可能性があります。 (この記事は主にjdk1.8に基づいています) Java ヒープオーバーフローJava ヒープはオブジェクト インスタンスを格納するために使用されます。オブジェクトを作成し続け、GC ルートからオブジェクトに到達可能なパスを確保して、ガベージ コレクション メカニズムがこれらのオブジェクトをクリアしないようにする限り、オブジェクトの数が増加するにつれて、合計容量が最大ヒープ容量制限に達し、メモリ オーバーフロー例外が発生します。 シミュレーションコード以下はヒープメモリのオーバーフローをシミュレートする簡単なコードです。
返される結果情報は次のとおりです。
問題分析メモリリーク(Memory Leak)なのかメモリオーバーフロー(Memory Overflow)なのかを特定する必要があります。
メモリリークJDK に付属する jvisualvm ツールを使用して、ヒープ スナップショット ファイルを読み込み、分析することができます。メモリ リークの場合は、さらにツールを使用して、リークされたオブジェクトから GC ルートまでの参照チェーンを表示し、リークされたオブジェクトがどの参照パスに関連付けられているか、およびどの GC ルートであるかを調べて、ガベージ コレクターによる再利用を防ぐことができます。リークされたオブジェクトの型情報と GC ルートへの参照チェーンに基づいて、通常、これらのオブジェクトが作成される場所をより正確に特定し、メモリ リークの原因となるコードの特定の場所を見つけることができます。 メモリリークメモリ リークではない場合、つまりメモリ内のオブジェクトが実際に存続する必要がある場合は、Java 仮想マシンのヒープ パラメータ (-Xmx および -Xms) 設定を確認し、マシンのメモリと比較して、上方調整の余地があるかどうかを確認する必要があります。次に、コードをチェックして、ライフサイクルが長すぎるオブジェクト、保持時間が長すぎるオブジェクト、不合理なストレージ構造設計などがないかどうかを確認し、プログラム実行中のメモリ消費を最小限に抑えます。 仮想マシン スタックとネイティブ メソッド スタック オーバーフローHotSpot 仮想マシンは、仮想マシン スタックとローカル メソッド スタックを区別しません。したがって、HotSpot の場合、-Xoss パラメータ (ローカル メソッド スタック サイズの設定) が存在しますが、実際には効果はありません。スタック容量は -Xss パラメータでのみ設定できます。仮想マシン スタックとネイティブ メソッド スタックに関しては、Java 仮想マシン仕様に次の 2 つの例外が記述されています。
Java 仮想マシン仕様では、Java 仮想マシン実装がスタックの動的な拡張をサポートするかどうかを選択することが明示的に許可されていますが、HotSpot 仮想マシンは拡張をサポートしないことを選択しています。そのため、スレッド作成時やメモリ申請時にメモリ不足が発生して OutOfMemoryError 例外が発生しない限り、拡張によりスレッド実行時にメモリオーバーフローが発生することはありません。スタック容量が新しいスタック フレームに対応できないため、StackOverflowError 例外が発生するだけです。 仮想マシンのスタックメモリオーバーフロースタックオーバーフローエラー サンプルコード:
例外情報を返します
メモリ不足エラー
出力:
要約するスタック フレームが大きすぎるか、仮想マシンのスタック容量が小さすぎるため、新しいスタック フレーム メモリを割り当てることができない場合、HotSpot 仮想マシンは StackOverflowError 例外をスローします。ただし、スタック容量の動的な拡張が可能な仮想マシン上で同じコードを使用すると、状況は異なります。 スレッドを作成するとメモリオーバーフローが発生する注意: 次の実験を行うと、オペレーティング システムがフリーズする可能性があります。仮想マシンで実行することをお勧めします。
メソッド領域とランタイム定数プールのオーバーフローランタイム定数プールはメソッド領域の一部であるため、これら 2 つの領域のオーバーフロー テストを一緒に実行できます。 HotSpot は JDK 7 から徐々に「永続世代をなくす」計画を開始し、JDK 8 ではメタスペースを完全に使用して永続世代を置き換えました。 メソッド領域のメモリオーバーフローメソッド領域の主な役割は、クラス名、アクセス修飾子、定数プール、フィールドの説明、メソッドの説明などの型関連の情報を保存することです。この領域をテストするための基本的な考え方は、実行時に大量のクラスを生成し、メソッド領域がオーバーフローするまで埋めることです。 Java SE API(GeneratedConstructorAccessorやリフレクション時の動的プロキシなど)を直接使用することでクラスを動的に生成することもできますが、今回の実験ではCGLibの助けを借りてバイトコードランタイムを直接操作することで、大量の動的クラスを生成しました。
出力コード
定数プールの例String::intern() は、文字列定数プールにこの String オブジェクトと等しい文字列がすでに含まれている場合に、プール内の文字列を表す String オブジェクトへの参照を返すネイティブ メソッドです。それ以外の場合、この String オブジェクトに含まれる文字列が定数プールに追加され、この String オブジェクトへの参照が返されます。 JDK 6 以前の HotSpot 仮想マシンでは、定数プールは永続世代に割り当てられます。 -XX:PermSize と -XX:MaxPermSize を通じて永続世代のサイズを制限できます。これにより、定数プールの容量が間接的に制限されます。
このコードを JDK 6 で実行すると、2 つの false 値が生成されますが、JDK 7 で実行すると、1 つの true 値と 1 つの false 値が生成されます。違いが生じる理由は、JDK 6 では、 intern() メソッドが最初に検出された文字列インスタンスを永続世代の文字列定数プールにコピーして保存し、永続世代の文字列インスタンスへの参照を返すためです。 StringBuilder によって作成された文字列オブジェクト インスタンスは Java ヒープ上にあるため、同じ参照になることはできず、結果は false を返します。 JDK 7 (および JRockit などの他の仮想マシン) の intern() メソッド実装では、文字列インスタンスを永続世代にコピーする必要がなくなりました。文字列定数プールは Java ヒープに移動されているため、定数プール内の最初のインスタンス参照のみを記録する必要があります。したがって、intern() によって返される参照は、StringBuilder によって作成された文字列インスタンスと同じです。 str2 の比較は false を返します。これは、String-Builder.toString() の実行前に文字列「java」がすでに出現しており、その参照がすでに文字列定数プール内にあるため、intern() メソッドで要求される「最初の遭遇」の原則を満たしていないためです。文字列「コンピュータ ソフトウェア」は初めて出現するため、結果は true を返します。 このマシンの直接メモリオーバーフロー直接メモリの容量は、-XX:MaxDirectMemorySize パラメータで指定できます。デフォルトでは、Java ヒープの最大値 (-Xmx で指定) と一致します。このコードは、DirectByteBuffer クラスをバイパスし、メモリ割り当てのリフレクションを介して Unsafe インスタンスを直接取得します (Unsafe クラスの getUnsafe() メソッドは、ブートストラップ クラス ローダーのみがインスタンスを返すように指定しており、これは、仮想マシンの標準クラス ライブラリ内のクラスのみが Unsafe 関数を使用できるようにするという設計者の希望を反映しています。JDK 10 では、Unsafe の一部の関数が VarHandle を介して外部使用に開放されました)。 DirectByteBuffer はメモリを割り当てるときにメモリ オーバーフロー例外をスローしますが、例外をスローするときにオペレーティング システムにメモリ割り当てを実際に要求するわけではありません。代わりに、計算によってメモリを割り当てることができないことがわかった場合は、コード内でオーバーフロー例外を手動でスローします。メモリ割り当てを要求する実際のメソッドは Unsafe::allocateMemory() です。
出力:
参考文献 「JVM仮想マシンの徹底理解 - 第3版」周志明 https://docs.oracle.com/javase/specs/jls/se8/html/index.html |
<<: Docker イメージの削減: 1.43G から 22.4MB へ
justhost、バレンタインデーの特別オファー:月額料金はたったの 2.25 米ドル、justho...
BandwagonHost VPS はいかがでしょうか?価格が高すぎるのですが、レンガ積みの作業はど...
tui56フォーラムの王宝塵さんのように、GoogleのPR値の更新を待っているウェブマスターは間違...
2012 年 6 月 28 日は、多くのウェブマスターや SEO 実践者に深い印象を残した日でした。...
Xinzhongxin Electronics Co., Ltd. は、キャンパス カード システム...
多くの人は、SEO はキーワード ランキングと同じだと考えています。実際、キーワード ランキングは ...
今日のオンライン金儲け業界では、タオバオアフィリエイトプロジェクトの競争が非常に激しいです。どの段階...
私はしばらく企業ウェブサイトの仕事をしてきましたが、SEOの専門家に比べると、私はまだ新人です。私た...
AWS IoT Device Management を使用すると、大規模な IoT デバイスを簡単か...
3月29日、国家発展改革委員会は「第12次5カ年計画期間における次世代インターネットの開発と建設に関...
Beanstalk は、高性能、軽量、分散型のインメモリ メッセージ キュー システムです。当初の設...
検索エンジンマーケティング業界には、ある程度、嘘や誤解を招く情報が溢れています。これらの誤解を招く情...
[51CTO.comよりオリジナル記事] 近年、消費者層の構造や消費パターンが変化し、顧客ロイヤルテ...
WeChat 5.0のリリースは大きな騒動を引き起こし、多くの人々に恐怖感を与えました。最も心配して...
reliablehostingservices.net は 2010 年に設立され、ドメイン名は 2...