web-dev-qa-db-ja.com

パーマスペースとヒープスペース

最初に、Permスペースとヒープスペースの違いは何ですか(JVMは各メモリスペースの使用をどのように選択しますか)。

第二に、しかし最も重要なことは、標準のMVCタイプJavaアプリケーションにどのような比率が推奨されますか?

78
Gareth

heapは、Javaプログラムによって作成されたすべてのオブジェクトを格納します。ヒープの内容はガベージコレクタによって監視されます。オブジェクトの使用を停止すると(つまり、オブジェクトへの参照がなくなったときに)ヒープからメモリを解放します。

これは、intやcharなどのプリミティブ型を格納するstackとは対照的であり、通常はローカル変数および関数の戻り値です。これらはガベージコレクションではありません。

perm spaceは、ヒープの特別な部分を指します。これを参照してくださいSO回答についての説明: perm spaceとは?

76
Olhovsky

個人的には、PermGenをヒープの特別な部分とは思わないでしょう。

ヒープは、オブジェクトインスタンスを保存するための専用メモリ領域として、PermGenはクラス定義を保存するための専用領域として考えることを望んでいます。その結果、PermGenのライフサイクルはJVMに関連付けられているのに対し、ヒープのライフサイクルはアプリケーションに関連付けられています。

アプリケーションとそのJVMが異なるライフサイクルを持つことができる最も良い例の1つは、Java EEコンテナーです。アプリサーバーでは、サーバーを再起動せずにアプリケーションをデプロイおよびアンデプロイできます。 (または再デプロイ)、すべてのオブジェクトインスタンス(ヒープスペース)を簡単に解放できますが、このアプリによって読み込まれたすべてのクラスをPermGenからクリアするのはかなり難しいです。

そのようなケースの1つは、 Leaking Drivers です。アプリがデプロイされると、JDBCドライバーが読み込まれ、DriverManagerに登録されます。このアプリがアンデプロイされると、DriverManagerはドライバ、その元のクラスローダー、およびこのクラスローダーが読み込んだすべてのものへの参照を保持します。その結果、PermGenでメモリリークが発生しますが、アプリケーションのメモリ管理に問題はありません。

JRocketのようなJVMにはPermGenがまったくなく、すべてがヒープに格納されているのは事実です。そのようなコンテキストでのみ、PermGenをヒープの「特別な部分」と呼ぶことができます。それでも、PermGenとヒープは、目的が大きく異なり、メモリリークの種類が非常に異なるため、異なる方法で表示する必要があります。

Update:OracleのJDK 8では、PermGenは "Metaspace"に置き換えられました であり、正式にヒープの一部になりました。 PermGenを特別に調整する必要はもうありません。

34

ヒープ内の割り当てられたメモリに名前を付けることはできません。

つまり、int x(その名前)がスタックに割り当てられます。ポインターには名前で到達できるため、ポインターはスタック内にあります。名前がないため、名前でオブジェクトに到達できません。 (名前のない)オブジェクトへのアクセスは、そのポインターによるものでなければなりません。

0
Pete Del Fina