この記事では、java に関する関連知識を提供します。主に、メモリ モデルの存在理由、同時プログラミング、メモリ領域とハードウェア メモリの関係など、メモリ モデルに関する関連事項を紹介します。待ってください、それが皆さんのお役に立てば幸いです。
推奨学習:「java チュートリアル」
面接では、面接官はよく次のように尋ねます。「Java とは何か教えてください。 「メモリモデル(JMM)?」 』
インタビュアーは大喜びで、この質問を暗記したばかりでした: 「Java メモリは主に 5 つの主要なブロックに分かれています: ヒープ、メソッド領域、仮想マシン スタック、ローカル メソッド スタック、PC レジスタ、バラバラ... "
面接官は知ったかぶりで微笑み、一筋の光を明らかにしました。「わかりました、今日の面接はここが先です。戻って通知を待ちます。」
一般的に、「待つ」というフレーズを聞くと、通知用」の可能性が高いインタビューです。とにかくカッコいいです。なぜ?面接官が概念を誤解していたため、面接官は JMM をテストしようとしましたが、面接官は JavaMemory
というキーワードを聞くとすぐに、八本足のエッセイを暗唱し始めました。 Java メモリ モデル (JMM) と Java ランタイム メモリ領域の間には大きな違いがあります。立ち去らずに読み続けてください。すべて読むと約束してください。
この質問に答えるには、まず従来のコンピューター ハードウェア メモリ アーキテクチャを理解する必要があります。さて、絵を描き始めます。
(1)CPU
コンピューター室に行ったことのある生徒は、通常、複数のサーバーが大規模なサーバーで構成されていることを知っています。これは、複数の CPU または複数のコアが同時に (同時に) 動作できることを意味します。 Java を使用してマルチスレッド タスクを開始する場合、各 CPU がスレッドを実行する可能性が高く、タスクは特定の瞬間に実際に同時に実行されます。 (2)CPU レジスタ
CPU レジスタは CPU レジスタです。 CPU レジスタは CPU 内に統合されており、レジスタに対する演算の実行効率はメイン メモリに対する演算よりも数桁高くなります。
(3)CPU キャッシュ メモリ
CPU キャッシュ メモリは CPU のキャッシュであり、レジスタと比較して、通常は L2 二次キャッシュにもなります。メモリの読み出し速度はハードディスクと比較すると非常に効率が良いですが、それでもCPUとは桁違いなので、そのためにCPUとメインメモリの間に多値キャッシュが導入されています。バッファリングの。
(4) メイン メモリ
メイン メモリはメイン メモリであり、L1 および L2 キャッシュよりもはるかに大きくなります。
注: 一部のハイエンド マシンには、L3 レベル 3 キャッシュもあります。
1.2. キャッシュの一貫性の問題
キャッシュを使用すると、CPU とメイン メモリのレートの不一致の問題は解決されますが、キャッシュの一貫性の問題という別の新しい問題も発生します。
マルチ CPU システム (またはシングル CPU マルチコア システム) では、各 CPU コアが独自のキャッシュを持ち、同じメイン メモリ (メイン メモリ) を共有します。複数の CPU の演算タスクが同じメイン メモリ領域に関係する場合、CPU は演算のためにデータをキャッシュに読み込むため、それぞれのキャッシュ データに不整合が生じる可能性があります。
したがって、各 CPU はキャッシュにアクセスするときに特定のプロトコルに従い、データの読み取りおよび書き込み時にそのプロトコルに従って動作し、共同してキャッシュの一貫性を維持する必要があります。このようなプロトコルには、MSI、MESI、MOSI、および Dragon Protocol が含まれます。
1.3. プロセッサの最適化と命令の並べ替え
。 CPU の実行効率をさらに向上させる方法はありますか?答えは、プロセッサの最適化です。
プロセッサがコードを最適化することに加えて、多くの最新のプログラミング言語コンパイラも同様の最適化を実行します。たとえば、Java のジャストインタイム コンパイラ (JIT) は命令の並べ替えを実行します。
上記では、ハードウェア関連の多くのことについて言及しました。一部の学生は少し混乱しているかもしれません。このような大きな円を経た後、これらのことは次のとおりです。 Java メモリ モデルは重要ですか? とは関係ありません。心配しないで、ゆっくりと下を見てみましょう。
Java の並行性に精通している学生は、「可視性の問題」、「原子性の問題」、および「順序付けの問題」という 3 つの問題についてよく知っている必要があります。これら 3 つの問題をより深いレベルで見ると、実際には、前述の「キャッシュの一貫性」、「プロセッサの最適化」、および「命令の並べ替え」によって引き起こされます。
キャッシュの一貫性の問題は、実際には可視性の問題です。プロセッサの最適化は原子性の問題を引き起こす可能性があり、命令の並べ替えは順序付けの問題を引き起こす可能性があります。それらはすべてつながっていると思いますか?
解決すべき問題は常に存在します。その解決策は何でしょうか?まず、単純で大雑把な方法を考えました。キャッシュを強制終了し、CPU がメイン メモリと直接対話できるようにすると、可視性の問題が解決します。プロセッサの最適化と命令の並べ替えを無効にすると、アトミック性と順序付けの問題が解決されますが、これは以前に戻ります。一夜にして解放されることは、明らかに望ましくないことです。
そこで技術部門の先輩たちは、物理マシン上に一連のメモリ モデルを定義して、メモリの読み取りおよび書き込み操作を標準化することを考えました。メモリ モデルは主に、同時実行性の問題を解決するために プロセッサの最適化を制限する
と メモリ バリアを使用する
という 2 つの方法を使用します。
同じ一連のメモリ モデル仕様でも、言語が異なると実装に多少の違いがある可能性があります。次に、Java メモリ モデルの実装原理に焦点を当てます。
JVM を知っている学生は、JVM ランタイム メモリ領域が断片化され、スタックやヒープなどに分割されていることを知っています。 , これらは、JVM によって定義される論理概念です。従来のハードウェア メモリ アーキテクチャには、スタックとヒープの概念がありません。
この図から、スタックとヒープはキャッシュとメイン メモリの両方に存在するため、この 2 つに直接の関係がないことがわかります。
Java メモリ モデルは多くのことを定義する仕様です:
テキストを読むのは退屈すぎるので、別の絵を描きました:
2 つのスレッドがすべて動作する場合共有変数。共有変数の初期値は 1 です。各スレッドは変数を 1 ずつ増分します。共有変数の期待値は 3 です。 JMM 仕様には一連の操作があります。
メイン メモリとローカル メモリ間の相互作用をより適切に制御するために、Java メモリ モデルでは、以下を実現するための 8 つの操作が定義されています。
4. 考え方のまとめ
データはキャッシュとメイン メモリの両方に存在します。標準化されていないと必ず災害が発生するため、従来のマシンではメモリ モデルが抽象化されています。
Java 言語は、メモリ モデルに基づいて JMM 仕様を発表しました。その目的は、マルチスレッドが共有メモリを介して通信する際のローカル メモリ データの不一致と、コンパイラによるコード命令の並べ替えと処理の問題を解決することです。プロセッサは、コードの順序どおりに実行されないなどの問題を引き起こします。
作業メモリとメインメモリ間の相互作用をより正確に制御するために、JMM では 8 つの操作 (
lock、unlock
、read
) も定義しています。 、load
、use
、assign
、store
、write
。 推奨学習: 「
以上が写真と文章で詳しく解説! Javaメモリモデルとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。