簡體   English   中英

類是否保存對其字段對象的引用?

[英]Does a class hold references to its field objects?

對於實例變量,尤其是字段,我對GC方面有些困惑。

因此,如果對象持有對其字段對象的引用,則在對象本身可以引用之前,這些對象將不符合垃圾回收的條件。 由於線程是GC的根,並且每個對象必須僅在某個線程上創建,因此線程不會放任在其上創建的任何對象,並且在收集垃圾之前,線程的整個對象層次結構將保留相當長的時間。

另一方面,如果一個對象放開了字段對象,則為這些對象調用getter方法將導致稍后返回null。

那么,這里的事實是什么?


澄清“現場物體”(如評論中所述)

  • 我所說的字段對象是對象本身的字段成員

編輯2:更多的闡述

因此,您會看到線程是通過線程對象實例在內存中具有表示形式的執行單元。 任何執行在任何地方的代碼執行都發生在某個線程上。

這種執行將如何發生?

好吧,通過在方法中執行一些代碼。 這將使該對象產生什么?

  • 局部變量

並且,這將使其成為GC根。

順便說一句,對於方法調用,該特定調用有一個堆棧,這就是我在這里所指的內容。

這並不像@ louis-wasserman所說的那么簡單- “是的,自然地”,或者就此而言,不是那么自然的 ..(?)

我進行了更多調查,並在...可能的預期位置找到了答案-Java語言規范

2.7。 對象的表示

Java虛擬機不要求對象具有任何特定的內部結構。

在Oracle對Java虛擬機的一些實現中,對類實例的引用是指向本身是一對指針的句柄的指針:一個指向包含對象方法的表的指針,以及指向表示對象的Class對象的指針對象的類型, 另一個分配給從堆為對象數據分配的內存

是的,這解決了。 即使JLS並沒有強制使用java.lang.Object的內部結構,也可能會使用類似於Oracle JVM的結構。

您可能會認為這具有更大的含義。 想象一個非常重的對象,其中包含一個非常龐大的成員字段對象。 嗯...可能是Bitmap 一個10MB的位圖和另一個對象僅保留圖像的標題:

bulky_object = {位圖,標題}

如果您將此對象創建為嵌套范圍內方法內部的局部變量(例如,),則在范圍結束后容器對象可以進行垃圾回收,但是如果您決定保留對位圖的引用(該字段)范圍之后的對象,則包含對象將不會被完全收集:

void someMethod(){

        // Outer block of the method
        bitmap_ref;

        // Nested block starts
        {
            some_object = new some_object();
            // Hold a ref to the bitmap
            bitmap_ref = some_object.bitmap;
        }
        // Nested block has ended. some_object is eligible for GC and is not accessible as a GC root
        // anymore

        // bitmap_ref shall remain available alive and well here as we are holding a ref to it
        // Also, some_object garbage collection may have happened leaving bitmap_ref alive
    }

這似乎是一個對象泄漏。

暫無
暫無

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

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