任务完成后,C#不释放内存 [英] C# not releasing memory after task complete

查看:829
本文介绍了任务完成后,C#不释放内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面code是一个问题,我看到了一个简单的例子。此应用程序作为字典太大抛出异常之前占用的内存约为4GB。

The following code is a simplified example of an issue I am seeing. This application consumes approx 4GB of memory before throwing an exception as the dictionary is too big.

 class Program
 {
    static void Main(string[] args)
    {
        Program program = new Program();

        while(true)
        {
            program.Method();
            Console.ReadLine();
        }
    }

    public void Method()
    {
        WasteOfMemory memory = new WasteOfMemory();
        Task tast = new Task(memory.WasteMemory);
        tast.Start();
    }


}

public class WasteOfMemory
{
     public void WasteMemory()
     {
         Dictionary<string, string> aMassiveList = new Dictionary<string, string>();

         try
         {
             long i = 0;
             while (true)
             {
                 aMassiveList.Add(i.ToString(), "I am a line of text designed to waste space.... I am exceptionally useful........");
                 i++;
             }

         }
         catch(Exception e)
         {
             Console.WriteLine("I have broken myself");
         }
     }
}

这是一切如预期,尽管当这个内存应该从CLR释放,我们目前还不能制定出什么。

This is all as expected, although what we cannot currently work out is when this memory should be released from the CLR.

我们已经让任务完成,然后模拟内存过载情况,而是由字典消耗的内存不会被释放。由于操作系统运行内存,是不是把pressure在CLR释放内存?

We have let the task complete and then simulated a memory overload situation, but the memory consumed by the dictionary is not released. As the OS is running out of memory, is it not putting pressure on the CLR to release the memory?

然而,更令人困惑,如果我们等到任务完成,然后按回车键再次运行内存被释放的任务,所以很明显的previous字典已经被垃圾回收(不是吗?)

However and even more confusing, if we wait until the task has completed, then hit enter to run the task again the memory is released, so obviously the previous dictionary has been garbage collected (hasn't it?).

那么,为什么内存没有被释放?我们又如何能得到CLR释放内存?

So, why is the memory not being released? And how can we get the CLR to release the memory?

任何解释或解决方案将大大AP preciated。

Any explanations or solutions would be greatly appreciated.

编辑:。以下答复,特别是Beska的,很明显我的问题的说明是不清晰的,所以我会尽量澄清

Following replies, particularly Beska's, it is obvious my description of the issue is not the the clearest, so I will try to clarify.

在code未必是最好的例子,对不起!这是一个快速原油一张code,试图复制的问题。

The code may not be the best example, sorry! It was a quick crude piece of code to try to replicate the issue.

本词典在这里用于复制的事实,我们有一个大的自定义数据对象,填补我们的记忆的一大块,它不然后释放任务完成后。

The dictionary is used here to replicate the fact we have a large custom data object, which fills a large chunk of our memory and it is not then released after the task has completed.

在这个例子中,词典填补了该词典的限制,然后抛出一个异常,它不保留填充永远!这是好之前我们的内存已满,并且它不会导致一个OutOfMemoryException。因此,结果是在存储器中的大的对象,然后在任务完成

In the example, the dictionary fills up to the limit of the dictionary and then throws an exception, it does NOT keep filling forever! This is well before our memory is full, and it does not cause an OutOfMemoryException. Hence the result is a large object in memory, and then the task completes.

在这一点上,我们所期望的字典是超出范围,因为这两个任务和方法方法已完成。因此,我们希望词典作为垃圾进行回收和存储回收。在现实中,内存不释放,直到法被再次调用,创建一个新的WasteOfMemory实例,并开始一个新的任务。

At this point we would expect the dictionary to be out of scope, as both the task and the method 'Method' have completed. Hence, we would expect the dictionary to be garbage collected and the memory reclaimed. In reality, the memory is not freed until 'Method' is called again, creating a new WasteOfMemory instance and starting a new task.

希望这将澄清这个问题有点

Hopefully that will clarify the issue a bit

推荐答案

好吧,我一直在关注这个...我觉得有几个问题,其中一些人已经触及,但我认为没有应答真正的问题(其中,无可否认,我花了一段认识到,我不知道我回答你想要的东西即使是现在。)

Okay, I've been following this...I think there are a couple issues, some of which people have touched on, but I think not answering the real question (which, admittedly, took me a while to recognize, and I'm not sure I'm answering what you want even now.)

这是一切如预期,尽管当这个内存应该从CLR释放,我们目前还不能制定出什么。

This is all as expected, although what we cannot currently work out is when this memory should be released from the CLR.

正如其他人所说,该任务运行时,该词典将不会被释放。它被使用。它变大,直到耗尽内存。我是pretty的一定要理解这一点。

As others have said, while the task is running, the dictionary will not be released. It's being used. It gets bigger until you run out of memory. I'm pretty sure you understand this.

我们已经让任务完成,然后模拟内存过载情况,而是由字典消耗的内存不会被释放。由于操作系统运行内存,是不是把pressure在CLR释放内存?

We have let the task complete and then simulated a memory overload situation, but the memory consumed by the dictionary is not released. As the OS is running out of memory, is it not putting pressure on the CLR to release the memory?

在这里,我想,是真正的问题。

Here, I think, is the real question.

如果我理解正确的话,你说你设置这填补内存。然后,崩溃后(但你打之前返回到开始一个新的任务),你想要的此程序之外的其他东西,比如在Windows中运行其他程序的尝试获得了气相色谱仪收集的内存,对不对?希望操作系统会谈论到GC,并开始pressuring它做的事情。

If I understand you correctly, you're saying you set this up to fill up memory. And then, after it crashes (but before you hit return to start a new task) you're trying other things outside of this program, such as running other programs in Windows to try to get the GC to collect the memory, right? Hoping that the OS would talk to the GC, and start pressuring it to do it's thing.

然而,更令人困惑,如果我们等到任务完成,然后按回车键再次运行内存被释放的任务,所以很明显的previous字典已经被垃圾回收(不是吗?)

However and even more confusing, if we wait until the task has completed, then hit enter to run the task again the memory is released, so obviously the previous dictionary has been garbage collected (hasn't it?).

我觉得你回答你自己的问题......它并没有被一定被释放,直到你打回启动一个新的任务。新的任务需要的内存,因此它去GC和GC的愉快地收集从previous任务,目前已结束(从全抛内存后)的内存。

I think you answered your own question...it has not been necessarily been released until you hit return to start a new task. The new task needs memory, so it goes to the GC, and the GC happily collects the memory from the previous task, which has now ended (after throwing from full memory).

那么,为什么内存没有被释放?我们又如何能得到CLR释放内存?

So, why is the memory not being released? And how can we get the CLR to release the memory?

我不知道,你可以强制GC释放内存。一般来说,它它时,​​它希望(尽管有些黑客类型可能知道一些华而不实的方式来迫使它的手。)当然,.NET决定何时运行GC,既然什么都没发生,而程序只是坐在那里,它很可能被决定,它并不需要。作为到OS是否可以pressure GC以运行,似乎从测试中的答案是否。有点违反直觉也许吧。

I don't know that you can force the GC to release memory. Generally speaking, it does it when it wants (though some hacker types might know some slick way to force its hand.) Of course, .NET decides when to run the GC, and since nothing is happening while the program is just sitting there, it may well be deciding that it doesn't need to. As to whether the OS can pressure the GC to run, it seems from your tests the answer is "no". A bit counter-intuitive perhaps.

难道这就是你想要知道的?

Is that what you were trying to get at?

这篇关于任务完成后,C#不释放内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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