java - 类是否保存对其字段对象的引用?

标签 java garbage-collection

当涉及到实例变量,尤其是字段时,我对 GC 方面有点困惑。

因此,如果一个对象持有对其字段对象的引用,则在该对象本身符合垃圾回收条件之前,这些对象将不符合垃圾回收条件。自 Threads are GC roots并且每个对象必须仅在某个线程上创建,thread won't let go of any objects created on it并且线程中的整个对象层次结构在被垃圾收集之前将保留相当长的时间。

另一方面,如果一个对象释放了字段对象,则为这些对象调用 getter 将最终返回 null。

那么,事实是什么呢?

<小时/>

对“字段对象”的澄清(如评论中所要求)

  • 我所说的字段对象是指对象的字段成员本身就是对象
<小时/>

编辑 2:进一步阐述

因此,您会看到线程是通过 Thread 对象实例在内存中表示的执行单元。任何地方发生的任何代码执行都发生在某个线程上。

这个执行将如何发生?

好吧,通过在方法中执行一些代码。什么会导致这个对象被创建?

  • 局部变量

并且,这将使其成为 GC 根。

顺便说一句,对于方法调用,该特定调用有一个堆栈,这就是我在这里提到的。

最佳答案

这并不像 @louis-wasserman 所说的那么简单 - “是的,自然” 或者就此而言,不是那么自然..(?)

我进行了更多调查,并在...您可能期望的地方找到了答案 - Java Language Specification

2.7. Representation of Objects

The Java Virtual Machine does not mandate any particular internal structure for objects.

In some of Oracle’s implementations of the Java Virtual Machine, a reference to a class instance is a pointer to a handle that is itself a pair of pointers: one to a table containing the methods of the object and a pointer to the Class object that represents the type of the object, and the other to the memory allocated from the heap for the object data.

是的,这就解决了。尽管 JLS 不强制要求 java.lang.Object 的内部结构,但可能会使用类似于 Oracle JVM 的结构。

这可能比您想象的有更大的含义。想象一下一个非常的对象包含一个非常庞大的成员字段对象。嗯...也许是一个位图。 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
    }

这里看起来像是对象泄漏。

关于java - 类是否保存对其字段对象的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52120242/

相关文章:

java - 如何更改整个 Swing UI 应用程序中的字体

java - 为什么我的recpie 显示此错误?

java - 如何将自定义参数传递给其余的获取网址?

java - 重复使用 Groovy Shells 会导致 PermGen 空间已满

asp.net - 追踪旧版 ASP.Net 网站上的内存泄漏

c++ - 什么时候需要在 Ruby C 扩展中声明 volatile VALUE?

java - JSONArray 到可用的 Java/字符串数组

java - 调整 GC Overhead Exceeded 参数

java.lang.OutOfMemory错误: GC overhead limit exceeded when loading an xlsx file

Java awt.Robot : send key with position for eg. 右移或右ctrl