如何释放内存? [英] How to deallocate the memory?

查看:118
本文介绍了如何释放内存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用正在使用WCF服务的应用程序。此服务将从其他某个应用程序调用,并将输出返回给调用者。这里的响应是具体对象的形式,类型的类型。



当这个应用程序将响应返回给调用者时,它甚至会保留一些内存。因此,一旦操作完成但仍保留内存,我尝试了不同的方法来释放这个内存。我试图解决这个问题的方法:



我尝试过:



我在返回响应之前创建了一个线程并调用了休眠函数1分钟。这次它有效。内存减少了,我收到了所需的输出。这是正确的方法吗?

我也尝试在finally块中处理响应对象但是在那种情况下内存减少了但我没有收到输出。

解决方案

如果您正在查看任务管理器以确定您的应用程序正在使用的内存量,请不要!这对你说谎。



你在任务管理器中看到的是你的应用程序执行的内存是多少,而不是它实际使用了多少内存。



.NET CLR管理应用程序的执行以及所谓的托管堆。当您的应用程序启动时,CLR会请求一块内存并将其放在托管堆中。应用程序创建的对象实例很快就会在托管堆上分配。如果堆内存不足,CLR将从Windows请求另一个块,并再次将其添加到堆中。这需要额外的时间,所以CLR试图通过查看你的应用程序分配的内容来向前看,并根据需要扩展堆,以保持应用程序的性能高。



CLR保持托管堆的大小具有舒适的余量,因此在每次分配时不必继续返回Windows以获得越来越多的内存,因为此过程需要时间并降低应用程序性能。



现在,当应用程序不再需要对象时,内存将被释放,但不会返回到Windows。它返回到托管堆。



任务管理器对.NET CLR及其保留的内存一无所知。它所看到的就是Windows所说的。 Windows正在告诉任务管理器,是的,我给了那个进程x大量的内存。我不知道它正在用它做什么。



但是,有还在Windows和.NET CLR之间进行协商。如果Windows开始内存不足,它可以要求.NET CLR返回它可以备用的任何内存,.NET CLR很乐意释放托管堆中任何未使用的内存并将其返回给Windows。



所有这一切都会自动发生,而不会让你搞砸它。任务经理可能会告诉你嘿,我们的内存耗尽!当你不是。 Windows只是没有感觉需要从.NET托管进程请求任何回来。


没有可接受的理由强制释放GC保存的内存......

(唯一可能的应用程序,当你可能知道更好的内存状态,然后GC是一个单实例/单用户应用程序...服务绝对不是其中之一......)

和......这是一个非常昂贵的操作...

和...... GC保留了记忆,因为没有人声称它,因为现在没有人需要它 - 所以为什么免费它?

了解GC:垃圾收集| Microsoft Docs [ ^ ]


Dave的文章很好地解释了内存管理。 GC管理内存的方式还有很多,但超出了本论坛的范围。快速谷歌搜索 [ ^ ]应该出现很多详细的文章,涵盖更精细的点。 br />


你唯一需要担心的是内存泄漏。这些通常仅在资源未释放时发生。试图强制GC执行它不会修复它,只修复代码。通常可以在调试器的诊断工具中看到内存泄漏。以下是一个快速介绍性视频:使用新的.NET内存诊断工具调试内存泄漏Visual Studio 2013启动|第9频道 [ ^

I am working on an application which is using WCF services. This service will get a call from some other application and will return the output to the caller. The response over here is in the form of concrete object which of type of a class.

When this application gave response back to the caller even then it is holding some memory. So iI tried different ways to deallocate this memory once the operation is done but it still holding the memory. Ways I tried to resolve the issue:

What I have tried:

I created one thread before returning the response and called the sleep function for 1 min. This time it works. The memory is reduced and I receive the desired output. is this the correct way?
I also tried to dispose the response object in finally block but in that case memory is reduced but I don't received the output.

解决方案

If you're looking at Task Manager to determine the amount of memory your app is using, DON'T! It's lying to you.

What you see in Task Manager is how much memory is RESERVED for your app's execution, NOT how much it's actually using.

The .NET CLR manages the execution of your application and what's called the "managed heap". When your app starts, the CLR requests a chunk of memory and places that in the managed heap. Object instances created by your application are allocated on the managed heap very quickly. If the heap is running low on memory, the CLR will request another block from Windows and, again, add it to the heap. This takes extra time so the CLR tries to "look ahead" by looking at what your app has been allocating and expands the heap as necessary to keep the performance of your app high.

The CLR maintains the size of the managed heap with a comfortable margin so it doesn't have to keep going back to Windows for more and more memory on every allocation since this process takes time and reduces your app performance.

Now, when objects are no longer needed by your application, the memory is freed, but NOT returned to Windows. It's returned to the managed heap.

Task Manager doesn't know anything about the .NET CLR and the memory it has reserved. All it sees is what Windows tells it. Windows is telling the Task Manager, "yeah, I gave that process x amount of memory. I have no idea what it's doing with it."

But, there is also a negotiation going on between Windows and the .NET CLR. If Windows starts running low on memory, it can ask the .NET CLR to return any memory it can spare and the .NET CLR will gladly free any unused memory in the managed heap and return it to Windows.

All of this happens automatically without you messing with it. Task Manager may tell you that "hey, we're running out memory!" when you're not. Windows just hasn't felt the need to go ask for any back from the .NET managed processes.


There is no acceptable reason behind forcibly freeing the memory GC holds...
(The only possible application when you may know better the state of memory then GC is a single-instance/single-user app... Service is definitely not one of them...)
and... It is a very expensive operation...
and... GC holds the memory because no-one claimed it, because no-one needs it now - so why free it?
Learn about GC: Garbage Collection | Microsoft Docs[^]


Dave's article does a nice job explaining memory management. There is more to how the GC manages memory however is beyond the scope of this forum. A quick google search[^] should turn up lots of detailed articles that cover the finer points.

The only thing that you need to really worry about are memory leaks. These usually only happen when resources are not released. Trying to force the GC to do it won't fix it, only fixing the code will. Memory leaks can usually be seen in the Debugger's Diagnostic tools. Here is a quick introductory video: Debugging Memory Leaks Using New .NET Memory Diagnostic Tools | Visual Studio 2013 Launch | Channel 9[^]


这篇关于如何释放内存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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