C/C++で開発したライブラリをJNIでJavaのラップを作ってみます。一番難しいところはメモリの回収だと思います。いろいろなメモリリックの問題を出ますので、一つ一つで解決して、最後まだリックされてることろがありました!ちょっと時間をかかって調べましたが、原因はGarbage Collectionとfinalizeの問題です。自分の調べた結果を簡単で纏めます。
一、Garbage Collectionとはガベージコレクション(garbage collection; GC)とは、プログラムが動的に確保したメモリ領域のうち、不要になった領域を自動的に解放する機能である。「ガベージコレクション」を直訳すれば「ゴミ収集」となる。
二、注意点
1、Garbarge CollectionはC++のデストラクタ関数ではありません
2、オブジェクト対象を解放する保証はありません。
三、GCが呼ばれるタイミング
1、アプリケーション占用したメモリ量が多い過ぎの場合
2、明示でSystem.gc()を呼び出す場合
例:
- /**
- * File: Chair0.java
- * @author Somebody
- */
- class Chair0{
- static boolean flag=true;
- static int finalizeNum=0;
- static int constructNum=0;
- Chair0()
- {
- constructNum++;
- }
- public void finalize(){
- flag=false;
- finalizeNum++;
- }
- }
- /**
- * File Garbage0.java
- * @author Somebody
- */
- public class Garbage0{
- public static void main(String []args){
- while(Chair0.flag){
- new Chair0();
- }
- System.out.println(”You have created “+
- Chair0.constructNum+” objects of Chair! And have finalized “+
- Chair0.finalizeNum+” objects “);
- }
- }
実行結果1:
- init:
- deps-jar:
- Compiling 1 source file to C:\Documents and ettings\Somebody\BomClass\build\classes
- compile-single:
- run-single:
- You have created 9783 objects of Chair! And have finalized 5 objects
構築成功 (合計時間: 0 秒)
- deps-jar:
- Compiling 1 source file to C:\Documents and ettings\Somebody\BomClass\build\classes
- compile-single:
- run-single:
- You have created 9783 objects of Chair! And have finalized 5 objects
構築成功 (合計時間: 0 秒)
ここまでの質問:
1、mainメソッドの終了するタイミング/条件は?
2、finalize()関数が呼ばれるタイミングは?
もう一つ例:
- /**
- * File MyClass.java
- * @author Somebody
- */
- class MyClass{
- private String name;
- public MyClass(String name){
- this.name=name;
- System.out.println(name+” is created.”);
- }
- protected void finalize() throws Throwable {
- System.out.println(”finalize “+name);
- }
- }
- /**
- * File: Garbage1.java
- * @author Somebody
- */
- public class Garbage1 {
- /** Creates a new instance of Garbage */
- public Garbage1(String i) {
- }
- public static void main(String []args){
- runrun();
- }
- public static void runrun(){
- MyClass myClass1=new MyClass(”myClass1″);
- new MyClass(”myClass2″);
- System.gc();
- int i=1;
- if(i==1)
- {
- MyClass myClass=new MyClass(”myClass3″);
- }
- System.gc();
- {
- MyClass myClass=new MyClass(”myClass4″);
- }
- System.gc();
- }
- }
実行結果2:
- init:
- deps-jar:
- Compiling 1 source file to C:\Documents and Settings\Somebody\BomClass\build\classes
- compile-single:
- run-single:
- myClass1 is created.
- myClass2 is created.
- myClass3 is created.
- finalize myClass2
- myClass4 is created.
- finalize myClass3
構築成功 (合計時間: 0 秒)
- deps-jar:
- Compiling 1 source file to C:\Documents and ettings\Somebody\BomClass\build\classes
- compile-single:
- run-single:
- You have created 9783 objects of Chair! And have finalized 5 objects
構築成功 (合計時間: 0 秒)
myClass2、myClass3がGCで回収されましたね。なぜmyClass4が回収されなかったですか。では、下記のソースを見ましょう。まだGarbage1です。
- /**
- * File: Garbage1.java
- * @author Somebody
- */
- public class Garbage1 {
- /** Creates a new instance of Garbage */
- public Garbage1(String i) {
- }
- public static void main(String []args){
- runrun();
- }
- public static void runrun(){
- MyClass myClass1=new MyClass(”myClass1″);
- new MyClass(”myClass2″);
- System.gc();
- int i=1;
- if(i==1)
- {
- MyClass myClass=new MyClass(”myClass3″);
- }
- System.gc();
- {
- MyClass myClass=new MyClass(”myClass4″);
- }
- System.gc();
- // myClass5のケースを追加します
- {
- MyClass myClass=new MyClass(”myClass5″);
- myClass = null;
- }
- System.gc();
- }
- }
実行結果3:
- init:
- deps-jar:
- Compiling 1 source file to C:\Documents and Settings\Somebody\BomClass\build\classes
- compile-single:
- run-single:
- myClass1 is created.
- myClass2 is created.
- myClass3 is created.
- myClass4 is created.
- finalize myClass3
- myClass5 is created.
- finalize myClass2
- finalize myClass4
- finalize myClass5
構築成功 (合計時間: 0 秒)
- deps-jar:
- Compiling 1 source file to C:\Documents and ettings\Somebody\BomClass\build\classes
- compile-single:
- run-single:
- You have created 9783 objects of Chair! And have finalized 5 objects
構築成功 (合計時間: 0 秒)
myClass2、myClass3、myClass4、myClass5が回収されました!
結論:
1、 終了するまで全部変数を回収するではありません。
2、 最後の変数スコープを無効になっても解放されない可能性があります。
3、 終了した後まだ回収されていないメモリをOSに渡して管理します。
4、 使っている対象に対して、GCは回収しておりません。(myClass1)
※参考(自分の別のブログなので、参考というのは大丈夫ですよね。^^!):
http://blog.minidx.com/2007/10/16/15.html
Posted on Monday, 20th October 2008 by admin
Tags: finalize, Garbage Collection, GC
Posted in Java | Comments (0) | 9,407 views
