プロが教えるわが家の防犯対策術!

Javaのメモリ管理についてご質問します。
下記の参考サイトを参考にしたのですが、JVMとして管理する部分とOSが管理する部分があるということが分かりました。
しかし、自分の理解が浅いせいか理解できない部分が3点あります。
<質問>
①LinuxでJavaプロセスが動いている時、topコマンドなどで出力される値(仮想メモリと物理メモリ)は、JVM管理する部分だけなのでしょうか?それとも、OSが管理する部分も含めた数値になるのでしょうか?

②OSが管理する部分とは、仮想メモリのことであっているのでしょうか?

③別のサイトでJVMは仮想メモリの管理・制御をしているが物理メモリの管理・制御はOS側で行っているとありました。ということは、JVMが使用してる仮想メモリがいっぱいになた際は仮想メモリを新たに割り当てることはあっても物理メモリを割り当てることはないということでしょうか?また、下記のサイトのOSが管理する部分ですが、こちらは仮想メモリも物理メモリの管理・制御もOS側で行っているのでしょうか?

うまく説明できていない様でしたら補足を行うのでご回答お願いいたします。また、参考になるサイト等ありましたらURLを送っていただけると幸いです。
皆さんのご教授お待ちしております。

[参考]
https://atmarkit.itmedia.co.jp/ait/spv/1005/13/n …

「JVM メモリ管理」の質問画像

A 回答 (2件)

① JVM管理部分と非管理部分を分けて見るのは難しいですね。


プロセスを止めてデバッグI/Fからメモリを分析すれば調べられると思いますが、そんなプログラムあるかな。JVMのメモリ管理も知らないと作れません。
topはよく知らないですけど、OS側からはメモリの種類はせいぜいコード(実行プログラム)、スタック(実行コンテキスト)、ヒープ(動的割当て領域)の区別くらいしかないでしょう。JavaVM固有領域はOSからみればすべてヒープです。
あと別の視点では、未割当て(論理アドレスだけ)・物理メモリ割当て・ファイル割当て(スワップアウト)の分類ですね。論理アドレス空間の分類です。

③ 仮想メモリを扱うOSの場合、実はアプリケーションからOSにメモリを要求する必要はないんですよね。アプリからは初めから2GBないしそれ以上の論理アドレス空間(連続メモリ)がみえて、使いたいだけメモリを割り振って作業します。それでアプリがあるアドレスに初めて書き込んだり読み出したりしたとき、OSの仮想メモリ管理が働いて未だメモリが割り当てられていないアドレスだったら(ページ単位で)物理メモリを割り当てます。それで物理メモリが足りなければ(他のアプリを含め)最近使っていない物理メモリをファイルに書き出して(スワップアウト)、その物理メモリを割り当てます。スワップアウトしてあるメモリ(論理アドレス)にアプリがアクセスしようとした時も同様です。適当に物理メモリを確保してスワップアウトしてあるファイルを読み込んで論理アドレスのメモリを使えるようにしてからアプリに続きの作業をさせます。なのでメモリ管理関係でOSコールをすることはなく、CPUのアクセス違反例外から仮想メモリ管理がメモリ割当てします。
それでJavaVMのメモリ管理はOSの仮想メモリ管理とはレイヤが違い、どの論理アドレスにどのJavaオブジェクトを配置するかの管理をします。なのでOSとJavaVMがメモリ管理を競合させるということはあり得ません。

なおJavaVMは使わないと思いますが、アプリが仮想メモリを制御する場合とは、リアルタイムで作業するプログラムが使うメモリがスワップアウトされるとリアルタイム性が損なわれるので特定の論理アドレスを物理メモリに固定配置してスワップアウトさせないというものです。一般に物理メモリ上に固定できるアドレスのサイズは非常に小さいものです。
あと特定の物理アドレスがデバイスの制御レジスタになっている場合にデバイスドライバで占有するようにさせるとか、そういうものもありますが基本特定の物理アドレスをOSのメモリ管理下から外すという話ですね。
    • good
    • 1

リンク先を読む限り図のOSネーティブの領域はJavaVM自体が使うメモリですね。

バイトコードを読み込むメモリとかインタプリタ自身のスタックとか。
① OSからみるとJavaVM固有領域を含め全てのメモリがOS管理のメモリです。topでみることができるのもこの全体です。JavaVMの外からはJavaVM固有領域かどうかは区別できず全てがOSからJavaVMに貸し与えたメモリです。
② これは質問の意図が読めません。
③ JVMを含めアプリケーションは基本的に仮想メモリ(論理アドレス空間)を扱い物理メモリは扱いません。アドレス空間のどの部分を物理メモリに割り当てるかはOSの責任です。リアルタイム性確保のために一部アドレスを物理メモリに割り当てるAPIが使える場合もありますけど。

Javaプログラムが新しいオブジェクトを作る時、JVMはまず自身が管理するメモリの中から空きを探してオブジェクトにメモリを割り当てます。足りなければGCを行って空きを確保し、それでも足りなければメモリオーバーフローとしてエラーを返すか、OSを呼び出して管理メモリを増やしてからその一部をオブジェクトに割り当てます。OSも割当てできない時はメモリオーバーフローとしてエラーを返します。最後のパターンだとOS自体が不安定になっていそうですけどね。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

①topコマンドでは全体しか見れないのですね。JVMが完治する部分とOSが管理する部分を細かく見るコマンドもあることにはあるということですよね?

②は③と似たことを聞いてしまいました。無視していただいて結構です。

③通常アプリケーションが直接物理メモリを確保し割り当ては行わず、必要になった際にOS側(MMU?)で仮想メモリに対応する物理メモリを割り当てるということですね。逆にOSから仮想メモリの制御を行うことはあるのでしょうか?その場合、OSとJavaVMがどちらも仮想メモリの制御を実施した場合はどちらの制御が優先されるものなのでしょうか?

お礼日時:2021/12/17 22:35

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!