切換
舊版
前往
大廳
主題

Java Programming Lesson 15

ジャネス | 2011-09-10 10:39:37 | 巴幣 0 | 人氣 927


Java言語プログラミングレッスン下巻

第15章:ガーベッジコレクション
。インスタンスの参照とガーベッジコレクション
 。インスタンスの生成と参照
 。インスタンスの参照をやめる
 。誰からも参照されていないインスタンス
 。引数として渡されるインスタンス
 。ガーベッジコレクタ
。ガーベッジコレクションの例
 。例:ガーベッジコレクションの動作確認
 。例:配列の例
 。ガーベッジになってくれないインスタンス
 。gcメソッド
。finalize
。学んだこと
。練習問題

★★★★★

。インスタンスの参照とガーベッジコレクション
 。インスタンスの生成と参照
  例:Something obj = new Something();
    変数obj Somethingクラスのインスタンスの場所のアドレスを参照してます
    new Something() Somethingクラスのインスタンスを1個作られる
 。インスタンスの参照をやめる
  例:Something obj1 = new Something(); // obj1にSomethingインスタンスを代入し、初期化
    Something obj2 = obj1;      // obj2に同じインスタンスを参照
    obj1 = null;           // obj1にnullを代入、何のインスタンスも参照しない
 。誰からも参照されていないインスタンス
  例:Something obj1 = new Something(); // obj1にSomethingインスタンスを代入し、初期化
    Something obj2 = obj1;      // obj2に同じインスタンスを参照
    obj1 = null;           // obj1にnullを代入、何のインスタンスも参照しない
    obj2 = null;           // obj2にnullを代入、何のインスタンスも参照しない
 。引数として渡されるインスタンス
  例:Something obj = new Something(); // objにSomethingインスタンスを代入し、初期化
    someMethod(obj);         // someMethodにobjのインスタンスのアドレスを引数として与えられ処理を行う
 。ガーベッジコレクタ
  。ガーベッジコレクタ(garbage collector)
   。ガーベッジコレクションを行う機構
  。ガーベッジコレクション(garbage collection)
   。誰からも参照されていないインスタンスが占めているメモリ領域を回収し、再利用する
   。プログラムは動作を一時に停止
   。メモリ空間を調べ、ガーベッジになったインスタンスを回収
   。再度新しいインスタンスを割り当てられ
   。メモリが無事確保できると、プログラムは動作を再開
  。本当にメモリが不足しているとき、OutOfMemoryErrorを発生する

★★★★★

。ガーベッジコレクションの例
 。例:ガーベッジコレクションの動作確認
GcTest1.java
----------
public class GcTest1 {
  public static void main(String[] args) {
    while (true) {
      String s = new String("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
      System.out.println("残りメモリ = " + Runtime.getRuntime().freeMemory());
    }
  }
}
----------
実行結果
javac GcTest1.java
java GcTest1
...
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27224264
残りメモリ = 27080072
残りメモリ = 27080072
残りメモリ = 27080072
残りメモリ = 27080072
残りメモリ = 26935840
...
----------

 。メモリ管理に関するメソッド一覧(java.lang.Runtimeクラス)
--------------
  public long freeMemory()
  例 // 利用可能なメモリの大きさを得る
    long free = Runtime.getRuntime().freeMemory();
--------------
  public long totalMemory()
  例 // 全メモリの大きさをバイト単位で得る
    long total = Runtime.getRuntime().totalMemory();
--------------
  public long maxMemory()
  例 // 最大メモリの大きさをバイト単位で得る
    long max = Runtime.getRuntime().maxMemory();
--------------
  public void gc()
  例 // ガーベッジコレクタを動作させる
    Runtime.getRuntime().gc();
--------------
  public static Runtime getRuntime()
  例 // 現在のRuntimeインスタンスを得る
    System.gc();
--------------

 。例:配列の例
GcArray1.java
----------
public class GcArray1 {
  public static void main(String[] args) {
    while (true) {
      int[] a = new int[1000];
      for (int i = 0; i < 1000; i++) {
        a[i] = i;
      }
      System.out.println("残りメモリ = " + Runtime.getRuntime().freeMemory());
    }
  }
}
----------
実行結果
javac GcArray1.java
java GcArray1
...
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23885272
残りメモリ = 23730576
残りメモリ = 23730576
残りメモリ = 23575856
← Ctrl+C で止める
----------

 。ガーベッジになってくれないインスタンス
GcArray2.java
----------
import java.util.*;

public class GcArray2 {
  static ArrayList list = new ArrayList();
  public static void main(String[] args) {
    while (true) {
      int[] a = new int[1000];
      for (int i = 0; i < 1000; i++) {
        a[i] = i;
      }
      list.add(a);
      System.out.println("残りメモリ " + Runtime.getRuntime().freeMemory());
    }
  }
}
----------
実行結果
javac GcArray2.java
java GcArray2
...
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
残りメモリ 55642024
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at GcArray2.main(GcArray2.java:7)
----------

 。gcメソッド
GcArray3.java
----------
public class GcArray3 {
  public static void main(String[] args) {
    for (int n = 0; true; n++) {
      int[] a = new int[1000];
      for (int i = 0; i < 1000; i++) {
        a[i] = i;
      }
      if (n % 100 == 0) {
        System.out.println("gcを呼び出します。");
        System.gc();
      }
      System.out.println("残りメモリ = " + Runtime.getRuntime().freeMemory());
    }
  }
}
----------
実行結果
javac GcArray3.java
java GcArray3
...
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
残りメモリ = 29434520
gcを呼び出します。
残りメモリ = 29759736
残りメモリ = 29759736
残りメモリ = 29759736
残りメモリ = 29759736
残りメモリ = 29759736
残りメモリ = 29759720
残りメモリ = 29601104
残りメモリ = 29442456
← Ctrl+C で止める
----------

★★★★★

。finalize
 。インスタンスの終了処理
 。開放用のメソッドとしてはclose、dispose、destroyという名前がよく使われる

★★★★★

。学んだこと
 。インスタンスの管理
 。「参照型」変数
 。ガーベッジコレクション

★★★★★

。練習問題

問題15-1
正しいものに○、誤っているものに×
× (1) Java言語にはガーベッジコレクションがあるので、メモリ不足のエラーが起きることはありません。
    「本当にメモリが不足しているとき、OutOfMemoryErrorを発生する」
○ (2) "null"という文字列を代入した変数は、どのインスタンスも参照していません。
○ (3) ガーベッジコレクタというのはメモリを再利用するための仕組みです。
○ (4) obj1が、あるインスタンスを参照しているとき、
     obj2 = obj1;
    という代入文によって、obj1とobj2は同じインスタンスを参照することになります。
× (5) obj1とobj2が同じインスタンスを参照しているとき、
     obj2 = null;
    という代入文によって、obj1が参照しているインスタンスはガーベッジになります。
    「obj2はどのインスタンスも参照していない、obj1はまだ参照している」
× (6) obj1がインスタンスを何も参照していないときにtrueとなる式は、
     obj1 = null;
    のように書きます。
    「正しいのは obj1 == null;」

問題15-2
List15-5のプログラムをjava GcQuizとして動かしたとき、55行目の※印の地点で生き残っている(参照されている)ClassAとClassBのインスタンスはどれでしょうか。その名前(name)で答えてください(例えば"ピーター"とか"トム"というふうに)。
【注意】
これはかなり面倒なパズルですが、インスタンスの管理についてきちんと理解しているかを試すために、いろいろ工夫がこらしてあります。この問題が解けたら、インスタンスの生成と参照についてかなり理解しているといえるでしょう。ですから、すぐに答えを見るのではなく、一歩一歩プログラムを読みながら図を描いて解いて下さい。

GcQuiz.java
----------
class ClassA {
  public static ClassA last = null;
  public String name;
  public ClassA(String name) {
    this.name = name;
    last = this;
  }
  public String toString() {
    return "[" + name + "]";
  }
}

class ClassB extends ClassA {
  public ClassA friend;
  public ClassB(String name) {
    super(name);
  }
  public ClassB(String name, ClassA friend) {
    super(name);
    this.friend = friend;
  }
  public String toString() {
    return "[" + name + ", " + friend + "]";
  }
}

public class GcQuiz {
  public static ClassA q = new ClassA("ジマイマ");
  public ClassA r = new ClassA("レベッカ");
  public static void main(String[] args) {
    ClassA a = new ClassA("ミトン");
    ClassA b = new ClassA("トム");
    ClassA c = new ClassA("モペット");
    ClassB[] arrayA = new ClassB[4];
    b = c;
    for (int i = 0; i < 4; i++) {
      arrayA[i] = new ClassB("犬" + i);
    }
    arrayA[3].friend = arrayA[3];
    arrayA[0] = arrayA[1];
    c = arrayA[2];
    arrayA[1] = null;
    ClassA d = arrayA[0];
    ClassB arrayB[] = new ClassB[4];
    arrayB[0] = new ClassB("フロプシー", new ClassA("野ネズミ"));
    arrayB[1] = new ClassB("モブシー", new ClassA("ナトキン"));
    arrayB[2] = new ClassB("カトンテール", c);
    arrayB[3] = new ClassB("ピーター", new ClassA("ベンジャミン"));
    arrayA = null;
    arrayB[0].friend = null;
    arrayB[1] = null;
    arrayB[2] = null;
    ClassB e = new ClassB("ルーシー", new ClassA("ティギー"));
    e = null;
    // ※ここの時点で参照されているインスタンスは何か
  }
}
----------
実行結果
javac GcQuiz.java
java GcQuiz
----------

★★★★★

第15章 終わり

創作回應

相關創作

更多創作