类是否包含对其字段对象的引用?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类是否包含对其字段对象的引用?相关的知识,希望对你有一定的参考价值。

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

因此,如果一个对象持有对其字段对象的引用,那么在对象本身之前,这些对象将无法进行垃圾收集。由于Threads are GC roots和每个对象必须仅在某些Thread上创建,因此thread won't let go of any objects created on it和Thread中的整个对象层次结构将在收集垃圾之前保留相当长的时间。

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

那么,这里的事实是什么?


澄清“现场对象”(如评论中所述)

  • 我认为,字段对象是对象的字段成员,它们本身就是对象

编辑2:更详细一点

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

这次执行将如何发生?

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

  • 一个局部变量

而且,这将使它成为GC的根源。

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

答案

它不是那么简单,就像@ louis-wasserman所说的那样 - “是的,自然地”,或者说那不是那么自然......(?)

我调查了一些,并找到答案...你可能会在哪里 - Java Language Specification

2.7。对象的表示

Java虚拟机不要求对象的任何特定内部结构。

在Oracle的一些Java虚拟机实现中,对类实例的引用是指向句柄的指针,该句柄本身是一对指针:一个指向包含对象方法的表和指向表示Class对象的指针对象的类型,另一个是从堆为对象数据分配的内存。

是的,这就解决了。即使JLS没有强制要求java.lang.Object的内部结构,也许可能会使用类似于Oracle JVM的结构。

你可能会想到这有更大的意义。想象一个非常重的物体,拿着一个非常庞大的成员场物体。嗯......也许是Bitmap。一个10MB的位图和另一个对象只是保存图像的标题:

bulky_object = {bitmap,title}

如果在嵌套作用域内的方法内创建此对象作为局部变量(例如,为了这个缘故),则在作用域结束后容器对象有资格进行垃圾回收但是如果您决定保留对该位图的引用(该字段) )对象在作用域之后,包含的对象将不会被完全收集:

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课后动手动脑 类与对象

包含对其自身实例的引用的标准向量的模板类

Android Studio:膨胀类片段时出错

mongodb关联查询

具有大量引用字段(数组除外)的对象是否会破坏Hotspot JVM的GC堆遍历性能?

(类对象和接口)