【问题标题】:Is there the concept of strong reference cycle (or something similar) in Java, similar to that of Swift? [duplicate]Java中是否有类似于Swift的强引用循环(或类似的东西)的概念? [复制]
【发布时间】:2017-02-16 00:18:11
【问题描述】:

在 Swift 中,非常强调强引用循环以及避免它的不同方法。如果两个变量之间存在强引用循环,它们将永远彼此保存在内存中,如果大图像或视频被强引用循环保存在内存中,则会导致程序崩溃。

我只是想知道Java中是否存在这样的概念?是否有可能无意中在 Java 中创建类似于强引用循环的东西?我有几个月的 Java 经验,但我从未听说有人在 Java 中提到过这样的概念,即使 Java 确实使用引用变量来指向对象。

【问题讨论】:

    标签: java swift variables


    【解决方案1】:

    似乎 swift 使用“引用计数”来检测对象的活跃度:每个对象都有一个与之关联的计数器,如果创建了对该对象的新引用,则该计数器会增加,如果对该对象的引用消失,则该计数器会减少。如果引用计数为零,则对象已死,这意味着不再有对它的引用。

    另一方面,Java 使用“可达性”作为活跃度的衡量标准:只要存在从某个“运行代码”到对象的引用链,一个对象就是活跃的。

    这两种方法各有利弊:

    • 引用计数使垃圾收集器的工作更轻松:只需查看引用计数,您就知道对象是否处于活动状态
    • 另一方面,引用计数可以在其他死对象之间创建引用循环
    • 可达性意味着垃圾收集器必须从线程可以直接到达的对象开始,并遵循所有引用来标记活动对象
    • 另一方面,可达性意味着引用循环没有问题:要么两个对象都可达,要么都不可达

    【讨论】:

    • 所以基本上垃圾收集发生在 Java 的运行时但在 Swift 的编译时?
    • @AliMir Swift 编译器只是添加了一些代码来支持垃圾收集器——垃圾收集过程本身总是在运行时发生。分配对象的方法可能永远不会被调用,一次或数百万次 - 编译器不知道也不在乎。
    • 引用计数在多线程环境中需要其他不必要的内存栅栏,这可能会导致性能下降。 stackoverflow.com/questions/2599238/…
    • @Basilevs 这不是唯一的问题。当计数器达到零时,引用计数 gc 必须采取行动,即释放对象的内存,归结为记住这块(可能相当小的)内存是空闲的,即使内存可能永远不会再次需要。然后,必须在某个点(如果可能)合并这些块,以获得更大的连续空闲内存块。复制/压缩 gc 仅在真正需要内存时运行,并且本质上会产生一个大的连续空闲内存块。如果有足够的备用内存,效率会更高。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多