2017-01-28 5 views
0

私はRubyを初めて使うので、何か不足していると私は謝ります。内部キャッシュのリフレッシュを実行するスレッドを開始するクラスがあります。スレッドに参加してnilに設定して、すべてのクラスインスタンスをnilに設定しても、そのクラスは破棄されません。誰もこの問題を見たことがありますか?私は間違って何をしていますか? Thxを ダニエルスレッドを開始するRubyクラスは決してGCによって破棄されません

マイREPRO:method(:bar).to_proc

  • シンボル検索に

    class KK 
        def initialize() 
         @thread = Thread.new(&method(:refresh_cache))  
         ObjectSpace.define_finalizer(self, self.class.finalize()) 
        end 
    
        def self.finalize() 
         proc {  
         puts 'Object KK Disposed' 
         } 
        end 
    
        def wait_thread 
         puts 'join thread' 
         @thread.join #also tried with exit and kill 
         @thread=nil 
        end 
    
        def refresh_cache 
          puts 'KK still here'  
        end  
    end 
    
    puts 'started' 
    
    puts Thread.list 
    
    k2=KK.new 
    puts ObjectSpace.each_object(KK).count 
    
    puts Thread.list 
    k2.wait_thread 
    k2=nil 
    puts 'After nil' 
    puts Thread.list 
    
    GC.start 
    sleep 5 
    #still one instance here 
    puts ObjectSpace.each_object(KK).count 
    
  • 答えて

    0
    1. &foo desugars foo.to_procから
    2. &method(:bar) desugarsがObjectから継承されたインスタンスメソッドである、methodを取得する必要がありますつまり、それはself.method(:bar).to_procです。

    self.methodは生きてバインドされた受信機(自己を)続けるバインドMethod、生産およびPROCに包まれたとき、それはそうやって続けています。

    インスタンスを保持せずにスレッドに渡すことができるプロシージャにする場合は、静的メソッドを使用する必要があります。

    +0

    ありがとうございます。私はスレッドがインスタンスメソッドにバインドされているので、私は参照を開いている、私の期待は一度私はそれをnilに設定スレッドを配置していた、それ自体を処分することができる。私が実装する必要があるキャッシュはインスタンスごとです(インスタンスはすべてデバイスです)。私はクラスメソッドを使用できません。私はRubyの新機能ですが、デストラクタが間違っています。 –

    +0

    GCが非同期で実行されるため、即時処理を期待するべきではありません。 – the8472

    +0

    これは私の方法です。スレッドプロパティをnilに設定しても、オブジェクトは決して破棄されません。とにかく皆さん、ありがとうございました。私はRubyの内部をもう少し学びましたが、その間にデバイスのインスタンスが作成され、コードのライフタイム全体にわたって維持されるように設計が変更されました。 –

    関連する問題