MDI形式的内存管理 [英] Memory management in MDI forms

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

问题描述

我要在子表单形成后销毁已使用的内存吗?

在孩子记忆之前收到的表格.
图片1
在孩子的记忆表现之后收到的表格.
图片2
关闭子窗体后从内存中读取.
图片3

Hi,Do I want to destroy the used memory after the child forms.

Forms received prior to the child''s memory performance.
Image 1
Forms received after the child''s memory performance.
Image 2
From memory after closing the child form.
Image 3

推荐答案

首先,停止查看任务经理查看您的应用程序实际使用了多少内存.骗你了

您在任务管理器中查看的数字是.NET CLR为您的应用程序保留的内容,而不是其实际使用的内容.

.NET维护托管堆.它从Windows获取一块内存,并将其放入托管堆中.当您为应用程序分配对象时,它从托管堆获取内存.完成对象处理后,内存将返回托管堆.

.NET CLR将释放所有可能的内存,并在需要时将其返回给Windows.

任务管理器向您显示的是Windows放弃了.NET CLR托管堆的内存.

如果您想查看应用程序的实际使用情况,请使用PerfMon和.NET Memory性能计数器,或者使用
First, stop looking in Task Manager to see how much memory your app is actually using. It''s lying to you.

The numbers you''re looking at in Task manager are what the .NET CLR has RESERVED for your application, NOT what it''s actually using.

.NET maintains a Managed Heap. It gets a chunk of memory from Windows and puts it into the managed heap. When you''re application allocated an object, it gets the memory from the managed heap. When you''re done with the object, the memory goes back into the managed heap.

The .NET CLR will free up any memory it can and return that back to Windows if needed.

What Task Manager is showing you is how much memory Windows has given up to the .NET CLR managed heap.

If you want to see what your app is really using, using PerfMon and the .NET Memory performance counters, or a .NET memory profiler[^].


通常,您无需释放受管系统中的内存,因为垃圾收集器(GC)会为您做到.内存的销毁和回收基于对象的可达性的概念:
http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29 [ ^ ].

这并不意味着您不会发生内存泄漏,但是首先,您需要了解内存泄漏.当您执行某些操作时,然后返回到有限状态机的状态图中的同一位置( http://en .wikipedia.org/wiki/Finite-state_machine [ ^ ]),则可到达对象的数量应该相同,并且应该等于之前在同一点上存在的对象.示例是:您在某个编辑器中打开和关闭多个文件,然后关闭它们.打开第一个对象之前,您应该拥有尽可能多的可到​​达对象.如果是这样的话,一切都会好起来的.不用担心.

这是否意味着您拥有相同的确切内存量?是的,没有.对象变得不可访问之后,将回收内存,但是无法保证确切的时间.迟早会发生.这是不应该使用任务管理器评估内存使用情况的另一个原因.您可以使用一种内存调试器,但是您应该清楚地了解发生了什么.请参阅:
http://en.wikipedia.org/wiki/Memory_debugger [ http://en.wikipedia.org/wiki/Weak_reference [ http://msdn.microsoft.com/en-us/library/system.weakreference.aspx [ ^ ].

最后,您的应用程序还可以通过P/Invoke或某种混合模式的汇编来使用托管内存,这在C ++/CLI中是可能的.请参阅:

http://en.wikipedia.org/wiki/P/Invoke [ http://msdn.microsoft.com/library/en-us/vcmxspec/html/vcmg_PlatformInvocationServices.asp [^ ],
http://www.codeproject.com/csharp/EssentialPInvoke.asp [ http://en.wikipedia.org/wiki/C%2B%2B/CLI [ ^ ],
http://www.ecma-international.org/publications/standards/Ecma-372.htm [^ ],
http://msdn.microsoft.com/en-us/library/dtefa218.aspx [ ^ ].

在这种情况下,应显式回收非托管内存.通常在接口System.IDisposable的方法Dispose的实现中执行此操作:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx [^ ].

重要的是要查看您使用的某种类型是否实现了此接口,并且不要忘记对其进行处理.最好尽可能使用using语句:
http://msdn.microsoft.com/en-us/library/yh598w02%28v = vs.110%29.aspx [ ^ ].



请查看我过去的答案:
垃圾回收负责所有内存管理 [ ^ ],
在循环内部延迟变量会导致内存泄漏吗? [ ^ ],
摆脱的最佳方法导致内存不足的公共静态列表 [ http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages [在WPF中使用MDI窗口的问题 [ ^ ],
MDIContainer提供错误 [如何最大程度地设置子表单,最小化最后一个子表单 [ ^ ].

…以及这个答案:
如何在WPF中创建MDI父窗口? [ ^ ].



检测可达性足够聪明.如果某个对象A引用了B,B引用了C,C引用了A,会发生什么情况呢?如果没有其他参考文献,它们会被回收吗?是他们会.你可以试试看.



根据 strong 的经验法则,最好不要触摸GC对象.最好的东西什么都不会改变,最好的话甚至会变得更糟.

—SA
Normally, you don''t need to free up memory in managed systems, because the Garbage Collector (GC) will do it for you. The destruction and reclaiming of the memory is based in the concept of reachability of an object:
http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29[^].

It does not mean that you cannot have memory leaks, but first, you need to understand the memory leak. When you do some operations, and then return to the same place in the state diagram of your finite state machine (http://en.wikipedia.org/wiki/Finite-state_machine[^]), the number of the reachable objects is supposed to be the same, and they should be equivalent to the objects which existed at the same point before. The example is: you open and close several files in some editor, and later you close them all. You should have as many reachable objects as before you opened the very first one. If this is the case, everything is all right. Nothing to worry about.

Does it mean you hold the same exact amount of memory? Yes and no. The memory is reclaimed after the object becomes unreachable, but the exact moment of time is not guaranteed. It can happen sooner or later. That is yet another reason why the Task Manager should not be used to assess the memory usage. And you can use one of the memory debuggers, but you should clearly understand what''s going on. Please see:
http://en.wikipedia.org/wiki/Memory_debugger[^].

Now, if everything is so good, how can you have memory leaks? First of all, by design. Imagine you work with files as I describe above, but you also cache some data to accelerate some search procedures. The problem is the life time of the cache: it should go beyond the life time of each file and be about the life time of the whole process. You can close all files, but what if you forget to clean out the data related to the file? It will remain in cache and so continue to be reachable. This is the leak. You can still allow reclaiming of the memory, if such cache (collection, some dictionary, or something) uses weak references instead:
http://en.wikipedia.org/wiki/Weak_reference[^],
http://msdn.microsoft.com/en-us/library/system.weakreference.aspx[^].

Finally, your application can also use managed memory via P/Invoke or some mixed-mode assembly, which is possible with C++/CLI. Please see:

http://en.wikipedia.org/wiki/P/Invoke[^],
http://msdn.microsoft.com/library/en-us/vcmxspec/html/vcmg_PlatformInvocationServices.asp[^],
http://www.codeproject.com/csharp/EssentialPInvoke.asp[^];
http://en.wikipedia.org/wiki/C%2B%2B/CLI[^],
http://www.ecma-international.org/publications/standards/Ecma-372.htm[^],
http://msdn.microsoft.com/en-us/library/dtefa218.aspx[^].

In this case, unmanaged memory should be explicitly reclaimed. It is very usual to do it in the implementation of the method Dispose of the interface System.IDisposable:
http://msdn.microsoft.com/en-us/library/system.idisposable.aspx[^].

It''s important to see if some type you use implements this interface and not to forget to dispose it. It''s the best to use the using statement whenever possible:
http://msdn.microsoft.com/en-us/library/yh598w02%28v=vs.110%29.aspx[^].



Please see my past answers:
Garbage collectotion takes care of all the memory management[^],
deferring varirable inside the loop can cuase memory leak?[^],
Best way to get rid of a public static List Causing an Out of Memory[^].



Please also understand that using MDI is bad thing. Please see:
http://en.wikipedia.org/wiki/Multiple_document_interface#Disadvantages[^].

Please also see my past answers:
Question on using MDI windows in WPF[^],
MDIContainer giving error[^],
How to set child forms maximized, last childform minimized[^].

…as well as this answer:
How to Create MDI Parent Window in WPF?[^].



Detection of reachability is smart enough. What happens if some object A has reference to B, B to C, and C to A? Will they be reclaimed, if there are no other references to them? Yes, they will. You can try it.



As a strong rule of thumb, it''s the best not to touch GC object; nothing essential will be changed, at best, or things could even go worse.

—SA


这篇关于MDI形式的内存管理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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