Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Javaメモリ勉強会

20,384 views

Published on

Java のメモリについて、2007/07/23 にアプレッソ社内向けに行った勉強会資料です。

Published in: Technology
  • Login to see the comments

Javaメモリ勉強会

  1. 1. メモリ勉強会 開発本部 吉田 哲也 2007/07/23
  2. 2. Java 仮想マシン仕様より <ul><li>Java 仮想マシン・スタック </li></ul><ul><li>ヒープ </li></ul><ul><li>メソッド・エリア </li></ul><ul><li>実行時コンスタント・プール </li></ul><ul><li>ネイティブ・メソッド・スタック </li></ul>
  3. 3. メモリモデルの概要 Java プロセスのメモリ領域 ヒープ領域 Java 仮想マシン スタック メソッド エリア ネイティブ メソッド スタック スレッド1 スレッド2 スレッド3 インスタンス インスタンス C 言語 クラス クラス “ abc” “ def” スレッド 1 用 スレッド 2 用 スレッド 3 用 -Xmx -Xss -XX:MaxPermSize
  4. 4. Java 仮想マシン・スタック <ul><li>他のプログラミング言語におけるスタック </li></ul><ul><li>フレームが格納される </li></ul><ul><li>フレームは下記を格納するためのもの </li></ul><ul><ul><li>ローカル変数 </li></ul></ul><ul><ul><li>中間的なデータ </li></ul></ul><ul><ul><li>メソッドの起動 </li></ul></ul><ul><ul><li>メソッドの戻り値 </li></ul></ul><ul><ul><li>例外のディスパッチ </li></ul></ul><ul><li>各スレッド毎 に生成され、スレッド終了時に破棄される </li></ul><ul><li>固定でも動的に拡張・縮小してもよい </li></ul><ul><li>ヒープ上に割り当てることも可能 </li></ul><ul><ul><li>Sun JRE ではヒープ上には割り当てられていない?? </li></ul></ul>
  5. 5. Java 仮想マシン・スタック <ul><li>最大サイズ・最小サイズをユーザに指定させても良い </li></ul><ul><ul><li>サイズ : -Xss ( 例 : -Xss1024) ※ 大きすぎる値 (2MB 以上 ) を指定するとパフォーマンスが大幅に遅くなる可能性あり ※ BEA Web サイトより </li></ul></ul><ul><ul><li>デフォルト : 512KB (1.4 以前で 1.5 は要調査 ) </li></ul></ul><ul><ul><ul><li>-server と -client によっても若干異なる </li></ul></ul></ul><ul><li>許容量を超える Java 仮想マシン・スタックが要求された場合には StackOverflowError がスローされる </li></ul><ul><li>Java 仮想マシン・スタック拡張時にメモリが確保できなかった場合には OutOfMemoryError がスローされる </li></ul>
  6. 6. 質問: スタック <ul><li>public static void main(String[] args) { StackOverFlowTest test = new StackOverFlowTest(); test.execute(); </li></ul><ul><li>} </li></ul><ul><li>private void execute() { execute(); </li></ul><ul><li>} </li></ul>
  7. 7. ヒープ <ul><li>全てのインスタンスや配列が格納される </li></ul><ul><li>スレッドで共有される </li></ul><ul><li>自動記憶管理システム (GC) によって回収される </li></ul><ul><ul><li>明示的にインスタンスが回収されることはない </li></ul></ul><ul><li>自動記憶管理システム (GC) アルゴリズムは Java 仮想マシン仕様では特定しない </li></ul><ul><ul><li>Java 仮想マシン実装者が選択可能 </li></ul></ul><ul><li>固定でも動的に拡張・縮小してもよい </li></ul><ul><li>最大サイズ・最小サイズをユーザに指定させても良い </li></ul><ul><ul><li>最大 : -Xmx ( 例 : -Xmx1024m) </li></ul></ul><ul><ul><li>最小 : -Xms ( 例 : -Xms1024m) </li></ul></ul><ul><ul><li>デフォルト (Sun JRE 1.5.x): </li></ul></ul><ul><ul><ul><li>最小 : マシンの物理メモリの 1/64 か、妥当な最小サイズかの大きい方。 簡単にテストしたところ 7MB くらいでした。 </li></ul></ul></ul><ul><ul><ul><li>最大 : 物理メモリの 1/4 か、 1GB かの小さい方。 </li></ul></ul></ul><ul><li>自動記憶管理システムが確保できるよりも大きなヒープが必要になった場合には OutOfMemoryError がスローされる </li></ul>
  8. 8. メソッド・エリア <ul><li>下記のものを格納する領域 </li></ul><ul><ul><li>実行コンスタント・プール </li></ul></ul><ul><ul><li>クラス毎の構造 </li></ul></ul><ul><ul><ul><li>フィールド </li></ul></ul></ul><ul><ul><ul><li>メソッド </li></ul></ul></ul><ul><ul><ul><li>コンストラクタ </li></ul></ul></ul><ul><li>別名パーマネント領域とも言う </li></ul><ul><li>スレッドから共有される </li></ul><ul><li>論理的にはヒープの一部 </li></ul><ul><ul><li>Sun の JRE ではヒープの一部となっていないようです </li></ul></ul><ul><ul><li>-Xmx を大きくすると – XX:MaxPermSize が取れません </li></ul></ul><ul><li>固定でも動的に拡張・縮小してもよい </li></ul><ul><li>最大サイズ・最小サイズをユーザに指定させても良い </li></ul><ul><ul><li>最大 : -XX:MaxPermSIze ( 例 : -XX:MaxPermSize=128m) </li></ul></ul><ul><ul><li>最小 : -XX:PermSize ( 例 : -XX:PermSize=128m) </li></ul></ul><ul><ul><li>デフォルト (Sun JRE): </li></ul></ul><ul><ul><ul><li>最大 : 64MB </li></ul></ul></ul><ul><ul><ul><li>最小 : 1MB </li></ul></ul></ul>
  9. 9. 質問 : クラスが GC の対象となるためには? <ul><li>ユーザ定義クラスローダによりロードされたクラス </li></ul><ul><li>ユーザ定義クラスローダへの参照がなくなった </li></ul>
  10. 10. 実行コンスタント・プール <ul><li>クラス毎、インタフェース毎に存在 </li></ul><ul><li>コンパイル時に決定される定数 </li></ul><ul><ul><li>数値リテラル </li></ul></ul><ul><ul><li>文字列リテラル </li></ul></ul><ul><ul><ul><li>“ aaa” のようにコンパイル時に決定される文字列 </li></ul></ul></ul><ul><li>実行時に解決しなければならないメソッドやフィールドの参照 </li></ul><ul><ul><li>クラスの構造体のようなもの </li></ul></ul><ul><li>メソッド・エリアから割り当てられる </li></ul><ul><li>実行時コンスタント・プールの構築に必要なメモリ容量がメソッド・エリアで利用可能なメモリ容量よりも大きい場合には OutOfMemoryError がスローされる </li></ul>
  11. 11. 質問: 文字列リテラル <ul><li>“ abc” == new String(“abc”) -> false </li></ul><ul><li>StringBuilder buf = new StringBuilder(); buf.append(“abc”); “abc” == buf.toString() -> false </li></ul><ul><li>“ abc” == new String(“abc”).intern() -> true </li></ul><ul><li>StringBuilder buf = new StringBuilder(); buf.append(“abc”); “abc” == buf.toString().intern() -> true </li></ul>
  12. 12. 文字列リテラル <ul><li>文字列リテラル </li></ul><ul><ul><li>String str = “a”; </li></ul></ul><ul><li>文字列リテラルではない </li></ul><ul><ul><li>new String(“aaa”); </li></ul></ul><ul><ul><li>Stream から呼んできたデータを文字列化 </li></ul></ul><ul><ul><li>StringBuffer および StringBuilder から生成した文字列 </li></ul></ul><ul><li>String#intern() メソッドは、実行コンスタント・プールにあるかどうかをチェックし、あれば実行コンスタント・プールにある文字列の参照を返し、なければ実行コンスタント・プールにプールして、その参照を返す。 </li></ul>
  13. 13. ネイティブ・メソッド・スタック <ul><li>native メソッドの実行を行うためのスタック </li></ul><ul><li>一般的にはスレッド毎に割り当てられる </li></ul><ul><li>固定でも動的に拡張・縮小してもよい </li></ul><ul><li>許容量を超えるネイティブ・メソッド・スタッククが要求された場合には StackOverflowError がスローされる </li></ul><ul><li>ネイティブ・メソッド・スタック拡張時にメモリが確保できなかった場合、新規スレッド用のネイティブ・メソッド・スタックが生成できなかった場合には OutOfMemoryError がスローされる </li></ul>
  14. 14. 質問: メモリモデルの概要 Java プロセスのメモリ領域 ヒープ領域 Java 仮想マシン スタック メソッド エリア ネイティブ メソッド スタック スレッド1 スレッド2 スレッド3 インスタンス インスタンス C 言語 クラス クラス “ abc” “ def” スレッド 1 用 スレッド 2 用 スレッド 3 用 Windows 32bit の場合の最大メモリ容量は? -> 2GB です
  15. 15. jvmstat <ul><li>http://java.sun.com/performance/jvmstat/ </li></ul><ul><li>Windows で使用する場合には若干の変更が必要 </li></ul><ul><li>変更方法はSNS に書いています。 </li></ul>

×