• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:JAVAにおけるメモリリーク)

Javaにおけるメモリリークとは?

OKTaro-の回答

  • ベストアンサー
  • OKTaro-
  • ベストアンサー率50% (36/72)
回答No.3

>クラスAの参照をnull にセットしさえすれば、 >内包されているクラスBに確保したメモリも即時に解放されるのでしょうか? まずクラスAもnullをセットしたとしても即時に開放される事はありません。 クラスAも同様に「どこからも参照されていない」状態になった時にGC(ガベージコレクション)の対象になるという事になります。 正確にいえば、参照の有無というよりはそのメモリ領域に対して到達可能かどうかです。 従ってクラスBにnullセットしなくてもクラスA自体が到達不能になり、クラスBの参照がAからしか参照されない場合、クラスBも同様に到達不能なので、GC対象です また変数にnullをセットするnullクリアについてですが、すごーく昔のjavaではnullセットする事でGCが早くなるというTipsはありましたが、これはもう現在では通用しません。 nullセットするコストの方が無駄なので、nullセットは推奨されません。 GUIなど参照が複雑なケースでのnullによる明示的な参照オフが必要な場合は除いて、バッドノウハウなので気をつけましょう >どういうときにJavaでメモリリークが起こるのでしょうか? 到達可能な状態でインスタンスを沢山保持してしまった場合です。 例えばクラスAはずっと使うが、内包するクラスBは一時的にしか使用しない場合、クラスBを使用しなくなった時点で参照を切らないと、クラスBはいつまでも使用しないにも関わらずGCされないという事です。 こういう例では明示的にnullクリアする必要があります

TeferiMage
質問者

お礼

> 例えばクラスAはずっと使うが、 > 内包するクラスBは一時的にしか使用しない場合、 > クラスBを使用しなくなった時点で参照を切らないと、 > クラスBはいつまでも使用しないにも関わらずGCされないという事です。 > こういう例では明示的にnullクリアする必要があります ありがとうございます。 このケースを意識しておこうと思います。

関連するQ&A

  • 無名パッケージのクラス

    パッケージ化されたクラス(pacA.ClassA)から、無名パッケージ(ClassB)のクラスを参照できるのでしょうか。 状況を詳しく書きますと、 ClassB はコンパイル済みで、pacA.ClassA の中で ClassB を new しています。 pacA.ClassA をコンパイルしたいのですが、ClassB を import できません(コンパイルエラー)。 それとも、ClassB は import する必要がなく、単に私のコンパイルの仕方(classpathの通し方等)が悪かったのでしょうか。 どなたか教えて頂けませんか。

    • ベストアンサー
    • Java
  • 継承元クラスのプロパティを参照する手段

    お世話になります。 ActionScrip3に関する質問です。 現在、カスタムクラスを勉強しております。 外部クラスでClassA、ClassBを作成し、 ClassAにある処理の途中でClassBを実行し、ClassBの中からClassAのプロパティを参照しにいく 処理を行いたいと思い、ClassBのコンストラクタからClassAのプロパティをtraceしました。 プロパティppt2は「かきくけこ」が出力されましたが、ppt1は「null」になってしまいました。 恐らく、タイムラインからClassAに対して設定したプロパティの値は見にいけていないようですが、 タイムラインから設定したプロパティの値を継承したClassBから参照しにいく方法はありますでしょうか? 下記ソースと同じ方法でなくても結構ですので、タイムラインから設定した スーパークラスのプロパティ値をサブクラスから参照・変更できる方法を ご教授いただければと存じます。 お手数ではありますが、宜しくご教授ください。 宜しくお願いいたします。 /* タイムライン側の処理 -----------------------*/ var test:ClassA = new ClassA(); test.ppt1 = "あいうえお"; test.goNext(); /* ClassAの処理 -----------------------*/ package {  // インポート記述は省略  public class ClassA {   var ppt1:String;   var ppt2:String = "かきくけこ";   // コンストラクタ   public function ClassA() { }   public function goNext():void {    var classb:ClassB = new classB();   }  } } /* ClassBの処理 -----------------------*/ package {  // インポート記述は省略  public class ClassB extends ClassA {   // コンストラクタ   private function ClassB() {    trace(ppt1);    trace(ppt2); }  } }

    • ベストアンサー
    • Flash
  • 参照メンバを持つクラス

    ClassAとClassBにCMyDataオブジェクトを渡したいのですが、メモリ上に同じデータのコピーを作りたくないので、コンストラクタがCMyDataの参照を受け取る設計にしました。こうすることで、CMyDataの実体はメモリ上に1つしか存在しないことになります。 ただ、クラスが、自身が管理していない外部領域にあるデータへの参照を使って仕事をするというのに違和感を感じます。 完全コンストラクタというデザインパターンがあって、クラスのインスタンスを生成する時に必要な全てのデータを渡すのが正しい流儀だそうです。 しかしこのClassA(B)の設計では、ClassA(B)の寿命が終わるまで参照先のデータが生きているとは限りません。もっといい設計はないでしょうか?ちなみにCMyDataは実際にはかなり大きなデータで、一時的であってもコピーを複数持ちたくないのです。ClassAとClassBは、実際は他のデータも参照するため1つのクラスにはしたくないのです。 class CMyData { // 色々なデータ }; class CMain { CMyData* myData; // ファイルからデータを読み込んで生成 ClassA* objA; ClassB* objB; void ReadFile() { myData = new CMyData(); // ファイルからデータを読み込みCMyData構築 } void Init() { ReadFile(); objA = new ClassA(*myData); // 自身のメンバ変数の参照でClassAを構築 objB = new ClassB(*myData); } void DoProcess() { Init(); // 実行は一度だけ objA->hoge(); // ClassAに仕事をさせる objB->foo(); // ClassBに仕事をさせる } } class ClassA { CMyData& m_data; public: ClassA(CMyData& data) m_data=data; // CMyDataオブジェクトを参照で受け取る void hoge(); } class ClassB { CMyData& m_data; public: ClassB(CMyData& data) m_data=data; // CMyDataオブジェクトを参照で受け取る void foo(); }

  • (クラス名.this.メソッド)って・・・?

    次のようなクラスで public class ClassA {   public static void main(String[]args)   {     new ClassA(); /* 構築A */   }   public ClassA()   {     new ClassI();   }   public class ClassI()   {     ClassA.this.MethodA(); /* 命令A */   }   public void MethodA()   {     System.out.println("HELLO");   } } この命令Aの部分の (クラス名.this.メソッド)というアクセス方法がよくわかりません とりあえす(ClassA.this)が構築Aの部分で生成された インスタンスではないかとおもうのですがそれで正しいのでしょうか? また インナークラスはインナークラスの定義されているクラス以外から インスタンスを生成できないのでしょうか? つまり次のクラスを追加して public class ClassB {   public ClassB()   {     new ClassA.ClassI(); /* 構築B */   } } ここの構築Bのように(この場合はダメの様ですが)他のクラスから 構築することです もし仮にできるとしたら そのときの命令Aの(ClassA.this)は一体なんの インスタンスを指すのでしょうか 急ぎのプログラムを作っているので たいへん不躾ですが、なるべく早くお答えをお願いします

    • ベストアンサー
    • Java
  • メモリリークの件

    メモリリークについて教えてください。 最近VC++を勉強中なのですが、メモリリークというものを知り、_CrtDumpMemoryLeaks()をしたところ、以下のコメントが出力されました。 [コメント] Detected memory leaks! Dumping objects -> strcore.cpp(118) : {71} normal block at 0x00344978, 20 bytes long. Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2E {48} client block at 0x003428E8, subtype 0, 64 bytes long. a CDynLinkLibrary object at $003428E8, 64 bytes long {43} client block at 0x00342720, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00342720, 64 bytes long {41} client block at 0x003425D0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $003425D0, 64 bytes long Object dump complete. スレッド 0x584 終了、終了コード 0 (0x0)。 上記のコメントから、メモリリークを起こしていることはわかりました。ただ、strcore.cppというクラスは作成していないのですが、エラーが出ます。 多分他の関数から呼ばれているクラスだと思うため、クラス等をコメントアウトして調べたのですが、エラーがまだ出力されます。 (Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2Eここは自作クラス上の問題だと思います。) newとかの解放はしているのですが、他にメモリリークをする原因ってあるのでしょうか?

  • [Obj-c]元クラスからサブクラスのメソッド

    Objective-Cの勉強をしています。 ClassAは元クラス(スーパークラス)です、 ClassB1、B2はClassAを継承(サブクラス)しています。 ClassAとClassB1にはiMethodというメソッドが存在します。 最下部にソースと実行結果があります。 ●そこで質問なのですが、  ClassAのインスタンスにClassB1のインスタンスをセットすると、  同じ名前のメソッドがあるだけでなぜClassB1のメソッドが呼ばれるのでしょうか?  (下記ソースの[bangai iMethod]; の部分です。)  ClassB1のインスタンスを渡すとClassAのインスタンスが  ClassB1のメソッドを使用できる理由がわかりません、  継承しているとはいえ型が違うものを参照渡しできる理由も今ひとつわからないです。  またこれはどういう機能を言うのでしょうか?  (例えば ポリモーフィズム、動的バインディングなど) ★ソース ------------------------------------------------------------------------------ #import <Foundation/Foundation.h> // ClassA @interface ClassA : NSObject { } @end @implementation ClassA -(void) iMethod { NSLog(@"スーパークラスのインスタンスメソッドです。\n"); return; } @end // ClassB1 @interface ClassB1 : ClassA @end @implementation ClassB1 -(void) iMethod { NSLog(@"サブクラスのインスタンスメソッドです。\n"); return; } @end // ClassB2 @interface ClassB2 : ClassA @end @implementation ClassB2 @end int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... ClassB1 *instance_B1 = [[ClassB1 alloc]init]; ClassB2 *instance_B2 = [[ClassB2 alloc]init]; [instance_B1 iMethod]; [instance_B2 iMethod]; // 親には子のクラスが入れられる ClassA *bangai = instance_B1; [bangai iMethod]; } return 0; } ------------------------------------------------------------------------------ ★実行結果 サブクラスのインスタンスメソッドです。 スーパークラスのインスタンスメソッドです。 サブクラスのインスタンスメソッドです。

  • メモリリークについて

    VC6.0でデバッグ実行すると Detected memory leaks! Dumping objects -> ソースファイル名(932) : {136739} normal block at 0x00FD4AC0, 0 bytes long. Data: <> メッセージがあり メモリがリークしているようです メッセージやソースから察するに 0バイトの領域を確保し それを解放したときに起こっているようです 領域をmallocして 解放ではNULLでなければ解放 という処理はしてはいけないことなのでしょうか 0バイトの領域を確保した場合 又は0バイトの領域を確保しないように 処理しないといけないのでしょうか? 知識のある方よろしくお願い致します

  • 親クラスのフリをした子クラスの使い方を教えて下さい

    以前、QNo.3479089でお世話になった者です。類似というか、続きの質問です。 ClassAを継承するClassBがあり、条件によって、ClassAまたはClassBをインスタンス化して使います。 (ClassBは、ClassAのメソッドの一部をオーバーライドして、ClassB固有のメソッドも追加しています) ClassA* pObj = NULL; if( ある条件 ) {   pObj = new ClassA(); } else( その他の条件 ) {   pObj = new ClassB(); } pObj->common_method(); これが常套手段と伺ったのですが、ClassBがインスタンス化された場合、ClassB固有のメソッドmethodBを呼び出そうとすると、「ClassAにはmethodBが存在しない」といったようなコンパイルエラーが出ます。 pObj->methodB(); // ここで、エラー それで、エラーを解消するために、「その他の条件」の時に、dynamic_castを使ってみました。 if( その他の条件 ) {   ClassB* pObj2 = dynamic_cast<ClassB*>( pObj );   pObj2->methodB(); } 上記でコンパイルエラーは解消したのですが、なにか、非常にめんどくさいです。 また、ClassAのフリをした実体ClassBを使っているのだから、オーバーライドしているメソッドもdynamic_castをしないと呼び出されないような気がします。 結局、親のフリした子クラスを作成する場合、こんなにめんどくさいことをしないといけないのでしょうか? それともこのやり方はおかしいですか? この場合、どういうふうにするものなのか、教えて下さい。よろしくお願いします。

  • メモリリークが発生するのはどういうときですか?

    メモリが解放されずに残るケースというのは、どういうときがあるのでしょうか? ※asp.netでプログラムを書いています。 (1)どのクラスも、基本的にコンストラクタでメモリが確保され、 どのクラスも、その親のオブジェクトが解放されたら、自分自身のメモリも解放される。 よって、画面のCloseで、すべてのオブジェクトのメモリは解放される。と思っています。 (2)スタティックメソッドで、参照渡しの引数があるとき、何度そのメソッドを使っても、 オブジェクトのポイントが渡るだけだし、処理完了後は、そのポインタすらも解放すると思っています。 (3)画面右上の「×」のボタン以外で画面が閉じてしまったとしても、セッションタイムアウトになった時点で、その分のメモリは解放すると思っています。 ◆どうしてdisposeメソッドがあるのでしょうか? .自分は、プログラム内に1箇所もdisposeを書く必要がないと思っていますが、どのような時に使うべきなのでしょうか?

  • Javaガーベジコレクションについて

    あるテキストにガーベジコレクションに関する次のような問題があります。  12. X3 x2 = new X3(); 13. X3 x3 = new X3(); 14. X3 x5 = x3; 15. x3 = x2; 16. X3 x4 = x3; 17. x2 = null; 18. // コードを挿入する オブジェクトをガーベジコレクションの対象にするには、18行目にどの1行を挿入しますか(2つを選択)。 A. x3 = null; B. x4 = null; C. x5 = null; D. x3 = x4; E. x5 = x4; 答えは、C とE になっていますが、どうしてそうなるのかどなたか分かりやすく教えていただけませんか。

    • ベストアンサー
    • Java