为什么GC不会收集未使用的对象 [英] Why GC does not collect an unused object

查看:154
本文介绍了为什么GC不会收集未使用的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图了解当不再使用某个对象时GC的行为,我的测试是不处理该对象(使用后),但它不起作用,该对象的析构函数从未被调用.

I'm trying to understand how the GC acts when an object is not being used anymore, my test is to do nothing with the object (after used) but it didn't work, the object's destructor was never called.

我创建了一个示例程序,尝试等待直到对象被销毁,但是运行4个小时后什么都没有发生.

I've created an example program trying to wait until the object is destroyed, but after 4 hours running nothing happens.

注意:我知道是否将对象设置为null,GC会收集它,但是我只想看看GC本身收集对象的正常"方式.

Note: I know if I set the object to null the GC will collect it, but I just want to see the "normal" way the GC itself collects the object.

using System;
using System.Collections.Generic;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
    internal class Program
    {
        private const string FilePath = @"C:\objLifeCycle.txt";

        private static void Main(string[] args)
        {
            var result = GetList();
            Console.WriteLine("Results received! Object Id: [{0}] time: [{1}]", result.ObjId, DateTime.Now);

            //result = null;

            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Thread.Sleep(2000);
                    Console.WriteLine("...");
                    GC.Collect();
                }
            });

            Console.ReadKey();
        }

        private static LinkList GetList()
        {
            return new LinkList(FilePath) { "link1", "link2", "link3" };
        }
    }
}

internal class LinkList : List<string>
{
    internal string ObjId { get; set; }

    internal string FilePath { get; set; }

    internal LinkList(string filePath)
    {
        ObjId = Guid.NewGuid().ToString();
        FilePath = filePath;

        WriteFile($"Object LinkList with Id [{ObjId}] has been created at [{DateTime.Now}]");
    }

    ~LinkList()
    {
        WriteFile($"Object LinkList with Id [{ObjId}] has been destroyed at [{DateTime.Now}]");

        Environment.Exit(0);
    }

    private void WriteFile(string line)
    {
        var sw = new StreamWriter(FilePath, true);
        sw.WriteLine(line);
        sw.Close();
    }
}

推荐答案

GC不会以确定的方式收集免费资源.该程序应该需要内存来请求资源.如果有足够的资源,GC将不会收集任何东西,因为没有必要.此外,GC只能在程序空闲"状态下收集内存...

GC will not collect free resources in a deterministic Way. The program should need memory to ask for resources. If there are enough resources the GC won't collect anything because there is not necessary. Also the GC could collect memory only in program "Idle" states...

我强烈建议您阅读:了解.NET垃圾收集

正如您可以测试并在文档中看到的那样,即使调用

As you can test and see in documentation there is no way to force a garbage collection even calling GC.Collect()

除此之外,您实际上还需要了解取决于平台和CLR实现的一些GC风格

And besides of that actually you need to understand that there are some GC flavors depending on platform and CLR implementations

跨VM对象集合

出于测试目的,您可以使用

For test purposes you can increase the need of Collect memory using GC.AddMemoryPressure Method (Int64)

这篇关于为什么GC不会收集未使用的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆