当前位置: 首页 > 知识库问答 >
问题:

垃圾收集-一个有效,但另一个无效,为什么?[副本]

洪光霁
2023-03-14

所以我有一个简单的Bell类,我正在测试垃圾收集:

public class Bell
{
    public void Ring()
    {
        Console.WriteLine("Ding ding");
    }
}

如果我运行下面的代码段,它不会被垃圾回收

class Program
{
    private static WeakReference reference;

    private static void Main()
    {
        Console.WriteLine("Starting");

        var bell = new Bell();
        reference = new WeakReference(bell);
        bell = null;

        GC.Collect();

        Console.WriteLine("Object still alive: {0}", reference.IsAlive);

        if (reference.Target == null)
        {
            Console.WriteLine("Bell is no more!");
        }
        else
        {
            {
                var theBell = (Bell)reference.Target;
                theBell.Ring();
            }
        }

        Console.ReadLine();
    }
}

如果我只是检查参考资料。我住在下面,垃圾被收集了

class Program
{
    private static WeakReference reference;

    private static void Main()
    {
        Console.WriteLine("Starting");

        var bell = new Bell();
        reference = new WeakReference(bell);
        bell = null;

        GC.Collect();

        Console.WriteLine("Object still alive: {0}", reference.IsAlive);

        Console.ReadLine();
    }
}

你们能给我解释一下这是怎么回事吗?

共有2个答案

全宪
2023-03-14

这是因为您的对象类型为参考(源代码

表示弱引用,该引用引用对象,同时仍然允许垃圾回收机制回收该对象。

下面可能解释了为什么两种情况表现不同(来源)

弱引用允许垃圾收集器收集对象,同时仍允许应用程序访问该对象。弱引用仅在不确定的时间内有效,直到在不存在强引用的情况下收集对象为止。当您使用弱引用时,应用程序仍然可以获得对对象的强引用,这会阻止收集该对象。但是,在重新建立强引用之前,垃圾收集器总是有先到达对象的风险。

经过几次运行[使用一些测试用例]:我的看法

我认为,if-else是关键。在Writeline之后,对象被重新引用,允许在GC清理对象之前获得强引用。

同样,这句话是关键

但是,在重新建立强引用之前,垃圾收集器总是有先到达对象的风险。

马博学
2023-03-14

您正在尝试使用调试模式对其进行测试。GC在调试模式下不具有攻击性,因为它在发布模式下(打开优化开关)表现良好。这使得调试变得容易,否则在调试时会发现奇怪的事情。例如:您可以尝试检查已垃圾回收变量的值。

在释放模式下运行代码,您可以看到Bell将被GC。

 类似资料:
  • 使用React,我有一个包含信息的div,其中另一个div包含项目列表。我希望第二个div(列表)可以在单击时折叠。如果我将click listener放在第一个div中,它将工作并显示项目列表。问题是它显示了所有项目的所有列表。我只希望单击项目的列表可见: 如果我在之后添加括号,我会收到以下警告: 警告:在现有状态转换期间(例如在

  • 如标题所述。我花了一些时间在一个客户的网站上实现一个特定的字体。我在所有需要的css类上实现了字体。 在定义菜单链接的“A”类中,调用字体不起作用。为什么? 参见截图1和2。 例如,在“div.powered-by”类(它也像链接一样工作)上,它可以工作,而在“a”类(它定义菜单链接)上则不行。见截图。 调用字体不起作用: Div.Powered-通过调用字体Works:

  • 在Java中,当一个对象没有实时引用时,它就有资格进行垃圾回收。对于字符串,情况并非如此,因为字符串将进入字符串池,而JVM将保持对象活动以供重用。这意味着字符串一旦创建就永远不会被垃圾收集?

  • 引用SCJP 6学习指南: 在方法中,您可以编写代码,将对所讨论对象的引用传递给另一个对象,从而有效地取消垃圾回收机制对该对象的资格。如果在同一对象稍后的某个时候再次有资格使用垃圾回收机制,垃圾回收器仍然可以处理并删除该对象。然而,垃圾回收器将记住,对于该对象,已经运行,并且不会再次运行 为什么设计成这样?方法的作用仍然有效,即使对象被第二次标记为收集。那么为什么Java决定跳过对的调用呢?

  • 问题内容: 是什么决定了垃圾收集器何时真正收集?它是在一定时间之后还是在一定数量的内存用完之后发生的吗?还是还有其他因素? 问题答案: 它在确定是时候运行时运行。在世代垃圾收集器中,一种常见的策略是在第0代内存分配失败时运行收集器。也就是说,每次你分配一小块内存(大块通常直接放置在“旧”代中)时,系统都会检查gen-0堆中是否有足够的可用空间,如果没有,则运行GC释放空间以使分配成功。然后将旧数据

  • Kubernetes 垃圾收集器的角色是删除指定的对象,这些对象曾经有但以后不再拥有 Owner 了。 注意:垃圾收集是 beta 特性,在 Kubernetes 1.4 及以上版本默认启用。 Owner 和 Dependent 一些 Kubernetes 对象是其它一些的 Owner。例如,一个 ReplicaSet 是一组 Pod 的 Owner。具有 Owner 的对象被称为是 Owner