2017-10-31 2 views
2

私はJava 8の 'closure'と少し混同しています。これは、値を超えていると思われます。 次のクラスを考えてみましょう。Java 8ラムダクロージャとGC

public class SomeClassWithLargeMemoryFootprint { 
    //some state 
    private SomeObject someObj; 
    //some more state 

    public void doSomething(SomeAsyncHelper helper) { 
     helper.doAsync(() -> { 
          //some super slow operation 
          int foo = someObj.whatever(); 
          //some more stuff  
         }); 
    } 
} 

//Let's assume SomeAsyncHelper.doAsync takes a VoidRunner that looks like below 
interface VoidRunner { 
    void apply(); 
} 

非同期ヘルパーがまだ動作しているときの質問は、SomeClassWithLargeMemoryFootprintのインスタンスがGC'dすることができますか? "someObj"はdoSomething()のラムダが必要とするためGCできません。残りの国はどうですか?

public class SomeClassWithLargeMemoryFootprint { 
    //some state 
    private SomeObject someObj; 
    //some more state 

    public void doSomething(SomeAsyncHelper helper) { 
     helper.doAsync(() -> { 
       //do something 
       memberMethod(); 
       //do something else 
       }); 
    } 

    private void memberMethod() { 
     //do something 
    } 

} 

今何:

また、私たちが含まれているクラスのメンバメソッドを呼び出す以下のバリアントを検討?どのように 'ヘルパー'は "memberMethod"の実行方法を知っていますか? SomeClassWithLargeMemoryFootprintのインスタンスへの参照を取得しますか? GCシーケンスは何ですか?

+0

私が知る限り、JavaのGCは参照カウントとJavaのlambdaを使用して、インラインクラスの文法上の砂糖に過ぎません。長い話は短いです:これはインラインクラスでこれをすべて実装するかのように機能します。インラインクラスはプライベートクラスなので、いつでも周囲のオブジェクト(およびその属性とメソッド)にアクセスできます。参照カウントは残りの部分とオブジェクトの正しい解放(ラムダが実行された後)を処理します。 – Turing85

+0

**これは確かに重複していますが、別の質問です。[Java8ラムダは、匿名クラスのようなその囲むインスタンスへの参照を保持していますか?](https://stackoverflow.com/a/28447015/581205)**参照https://stackoverflow.com/a/23991339/581205 – maaartinus

答えて

1

Asyncヘルパーがまだ動作しているときにSomeClassWithLargeMemoryFootprintのインスタンスをGCすることはできますか?

いいえ。VoidRunnerインスタンスは、その包含するSomeClassWithLargeMemoryFootprintオブジェクトへの強い参照を持ち、何らかの形で非同期タスクエグゼキュータによって参照されます。それで、GCできません。

残りの州はどうですか?

残りの状態はSomeClassWithLargeMemoryFootprintのインスタンスによって参照されるため、GCできません。

は「ヘルパー」は

それが最初の例ではsomeObj(すなわちthis.someObj)にアクセスする方法を知っているのと同じ方法を「memberMethod」を実行する方法を知っているんどのように:それはその囲んへの参照を持っていますSomeClassWithLargeMemoryFootprintオブジェクト(すなわち、this)。

+0

クール..ありがとう!匿名クラスが囲むクラスへの参照を保持しているという事実により、明らかになります。 –

+0

フォローアップの質問:lambdaの囲むクラスのメンバーにアクセスしていないときに、囲んでいるクラスへの強い参照を解除する方法はありますか?それで、ラムダを使う利便性からあまりにも発散していない、きちんとしたやり方を意味します。ラムダインタフェースを実装する具体的なクラスではありません。 –

+0

私はラムダでインターフェイスの静的な最終インスタンスを作成し、その周りを渡すことができたと思います... –