簡體   English   中英

在匿名類構造函數中引用最終對象是否泄漏?

[英]Reference to final object in anonymous class constructor a leak?

我正在將一個runnable傳遞給一個服務。 可運行的持續時間可能比通過它的片段/活動壽命更長。 我想知道以下代碼片段是否會通過在runnable中維護引用來泄漏frag對象? 我意識到我可以在runnable之外移動包含frag的整行(就像我用“String key = frag ...”所做的那樣),但我只是想要了解匿名類如何/何時泄漏賓語。

我真的不確定。 runnable只需要frag來在初始化實例時確定變量,並在此處進行內聯初始化。 因此從理論上講,在創建內聯實例后,不需要對frag進行任何引用。

如果我在run()函數中有一個對frag的引用,我會認為泄漏然后會得到保證,因為它需要保持frag存活以便將來某個時候引用它(而且很可能是碎片的gc'd點,但供參考)。

private static void fg_downloadFile(final FragMyDrive frag, final File file, final Drive drive){

    final String key = frag.getCastedActivity().getKey();

    Runnable rx_downloadFile = new Runnable() {

        Context ServiceContext = frag.getCastedActivity().mService;

        @Override
        public void run() {

            bg_downloadFile(ServiceContext, key, file, drive);
        }
    }; 

    //.... Submit runnable to service...
}

您可能知道,在向外聲明變量時必須使變量成為最終變量,但在匿名類中使用它們。 這里的Java技巧是所有這些變量復制到該匿名類的隱式生成的實例字段中。

話雖如此,但這意味着確實存在實例字段(在您的runnable中),其中包含外部作用域的所有訪問變量的副本。 在您的示例中,它也會引用FragMyDrive因為您只是訪問它。

在您的runnable有資格進行垃圾回收的同時,所有這些對象都有資格進行垃圾回收。 這意味着在runnable中對FragMyDrive的引用會使該對象保持活動狀態,只要它正在運行。

將這些引用縮小到您真正需要的范圍始終是一個好主意:

private static void fg_downloadFile(final FragMyDrive frag, final File file, final Drive drive){
    final String key = frag.getCastedActivity().getKey();
    final Context context = frag.getCastedActivity().mService;

    Runnable rx_downloadFile = new Runnable() {
        @Override
        public void run() {
            bg_downloadFile(context, key, file, drive);
        }
    }; 
    //.... Submit runnable to service...
}

這里唯一(隱式生成的)實例字段是:

String key
Context context
File file
Drive drive

我不確定我是否理解你對內聯詞的正確使用,但無論如何,我認為這里沒有任何泄漏。

Var final String key只是靜態函數fg_downloadFile()的本地引用,因此在函數fg_downloadFile()超出范圍時會釋放它。

只要Runnable線程存在, Runnable匿名內部類仍然可以保持引用(再次,不是對於frag而是對其中的某些子屬性)。 (更確切地說,編譯器實際上使用構造函數和final成員變量生成Runnableimplementation ,該變量將任何隱式使用的引用復制到fg_downloadFile()范圍內可用的任何引用。)

但無論如何,一旦所有代碼都被執行,所有對frag (子成員)的引用都將被刪除,垃圾收集器可以拾取垃圾。

希望這可以幫助。

有趣的問題。 你有沒有自動垃圾收集的編程經驗,比如Objective C?

但是要回答你的問題,我不明白為什么會出現泄漏。 我想會發生的事情是Runnable將保留對frag的引用以供它自己使用,但是在將來的某個時候,一旦服務不再需要它,frag也會被垃圾收集,因此它不會引用它。

當垃圾收集工作時,一旦不再引用對象,它將受到垃圾收集和解除分配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM