2016-09-29 4 views
1

Eclipse RCPアプリケーション内で依存性注入(DI)を使用しています。私は以下のようなコードを実行するクラスがたくさん持っている:私はjvisualvmを使用してアプリケーションを監視する場合メモリリーク/ ContextInjectionFactory/IEclipseContext

public class SomeClass { 
    @Inject 
    private IEclipseContext context; 

    private SomeObject void someMethod(){ 
     SomeObject someObject = 
      ContextInjectionFactory.make(SomeObject.class, context); 
     // Do stuff with someObject 
    } 
} 

を、私はこれのためにメモリリークがあると気づきます。 EclipseContextオブジェクトは、最終的にメモリ不足になるまで成長を続けます。

私は次の操作を行う場合は、メモリリークが消える:

public class SomeClass { 
    @Inject 
    private IEclipseContext context; 

    private SomeObject void someMethod(){ 
     IEclipseContext childContext = context.createChild(); 
     SomeObject someObject = 
      ContextInjectionFactory.make(SomeObject.class, childContext); 
     childContext.dispose(); 
     // Do stuff with someObject 
    } 
} 

私は私の回避策をやってサポートしているすべてのドキュメントを見ていません。クラスの作成後にchildContextを破棄することに否定的な副作用はありませんか?遭遇したことのないCIFを使用すると全体的に優れたアプローチがありますか?

私のコードには多くのクラスがあり、その中には@ Sington/@Creatableというアノテーションが付けられています。これらが廃棄された親コンテキストによって影響を受けるかどうかはわかりません。

ありがとうございます!

+0

私は漏れがあるという報告を見たことがなく、私のコードではこれを見ていません。 –

+0

それは間違いなく間違いです。私のコードの唯一の違いは、上記のものです。私は多くのオブジェクトを作成します。オブジェクトの多くは、もはや必要なくなったときに破壊されます。数日のうちに、主なコンテキストには何百万ものオブジェクト参照があり、メモリエラーが発生するまでそれが成長しています。回避策を実行するとすべてがうまくいく。回避策を使用することによる悪影響をご存知ですか? – ekjcfn3902039

+0

子コンテキストを使って何かを実行すると、IEclipeContextが注入された場合、後でそれにアクセスしようとすると、破棄されたコンテキストにアクセスすることになります。これにより、エラーをデバッグするのが困難になります。これらの参照をすべて格納しているEclipseContextクラスのフィールドを知っていますか? –

答えて

2

あなたはこのようなあなたのクラスのフィールドを設定するための注射を使用します。

public class Test 
{ 
    @Inject 
    private StatusReporter rep; 
    @Inject 
    private IEventBroker broker; 


    public Test() 
    { 
    } 
} 

EclipseはEclipseのコンテキストの値が変更された場合、それはフィールドを再注入することができるように注入された各フィールドを追跡する必要があります。これには、注入されたフィールドごとにTrackableComputationEx‌​t‌​ContextInjectionList‌​enerのオブジェクトが作成されます。

次のようにコンストラクタで値を挿入代わりにした場合:

public class Test 
{ 
    private StatusReporter rep; 
    private IEventBroker broker; 

    @Inject 
    public Test(StatusReporter rep, IEventBroker broker) 
    { 
    this.rep = rep; 
    this.broker = broker; 
    } 
} 

Eclipseはこれらのオブジェクトが作成されません(しかし、あなたはまた、文脈があれば更新情報を取得することはありませんので、コンストラクタインジェクションを追跡する必要がありません値は変更されます)。

これをテストすると、作成された1つの内部使用トラッキングオブジェクトがあるように見えます。

+0

フィールド注入とコンストラクター注入を使用したコードの多くを見て以来、私がしたのと同じことを誰も言及していないのは奇妙です。クラスが使用されなくなった後も追跡オブジェクトは消えますか?コレクションオブジェクトがあり、コレクションをクリアした場合、トラッキング参照はなくなりますか?私は(私が見たことのあるインスタンスの数で)フィールド注入ではないと思っています(たとえ私がそれらを期待していても) – ekjcfn3902039

+0

Well Javaは、何かが「離れる」ときに追跡する方法がありません私が見逃していたどこかのWeakReferenceがない限り)おそらくそうではありません。コンテキストが破棄されるまで、おそらく周りにハングアップします。しかし、このコードは非常に複雑で読みにくい(通常通り)。私はほとんどの人が限られた数のUIオブジェクト上でのみ注入を使用していると思いますので、これを打つことはありません。 –