.NET可用内存使用情况(如何防止OS释放内存/释放内存) [英] .NET Free memory usage (how to prevent overallocation / release memory to the OS)

查看:140
本文介绍了.NET可用内存使用情况(如何防止OS释放内存/释放内存)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在致力于大量使用缓存数据的网站,以避免往返。
在启动时,我们得到一个大图(数百种不同种类的物体)。
这些对象通过WCF检索并反序列化(我们使用协议缓冲区进行序列化)
我使用redgate的内存分析器来调试内存问题(内存似乎不适合我们应该占用多少内存需要之后我们完成初始化并结束本报告





现在我们可以从这份报告中收集到的是:

1 )大部分.NET分配的内存都是免费的(它可能在反序列化过程中被正确地分配了,但现在它已经是免费的了,我希望它能够返回到操作系统)

2)内存碎片化(这是坏的,因为每次我刷新现金,我需要重做内存饥饿的反序列化过程,这反过来会创建一个大对象,可能会由于碎片而抛出OutOfMemoryException)。



3)我不知道为什么这个空间是零散的,因为当我看着这个大对象时,他ap,只有30个实例,15个对象[]直接连接到GC并与我完全无关,1是直接连接到GC堆的char数组,其余15个是我的,但不是这个的原因如果我在代码中注释它们,我会得到相同的报告。



所以我的问题是,我能做些什么来进一步处理这个问题?我不太清楚在调试/工具中需要寻找什么,因为它似乎是我的内存碎片化的,但不是我自己的,大量的空闲空间由.net分配,我无法释放。



另外请确保您在回答之前很好地理解问题,我不想在.net(GC.Collect)中释放内存,但释放已经存在的内存如果可以手动对大堆进行碎片整理,那么可以使用.net,f​​ree到.net,以及对所述内存进行碎片整理。



因为我可以在RefreshCache结束时调用它,并且它可以运行1或2秒。



感谢您的帮助!

p>

我忘记了一些笔记:
1)该项目是一个.net 2.0网站,我得到了在.net 4池中运行它的相同结果,如果我将它运行在.net 4池中,并将其转换为.net 4并重新编译。


2)这些是发布版本的结果,因此调试版本不能成为问题。



3)这可能相当重要,我在webdev服务器中完全没有得到这些问题,只有在IIS中,在webdev我获得的内存消耗与我的实际消耗量相当接近(好得多,但不是5-10倍!)

解决方案

大对象堆(对象> = 85,000字节,通常是数组)不会被垃圾收集器压缩。微软决定移动这些对象的成本太高。


建议在可能的情况下重用大对象以避免
碎片化在托管堆和VM空间上。

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx



我假设你的大对象是由你的反序列化库创建的临时字节数组。如果库允许你提供你自己的字节数组,你可以在程序开始时预分配它们,然后重用它们。


I'm currently working on a website that makes large use of cached data to avoid roundtrips. At startup we get a "large" graph (hundreds of thouthands of different kinds of objects). Those objects are retrieved over WCF and deserialized (we use protocol buffers for serialization) I'm using redgate's memory profiler to debug memory issues (the memory didn't seem to fit with how much memory we should need "after" we're done initializing and end up with this report

Now what we can gather from this report is that:

1) Most of the memory .NET allocated is free (it may have been rightfully allocated during deserialisation, but now that it's free, i'd like for it to return to the OS)

2) Memory is fragmented (which is bad, as everytime i refresh the cash i need to redo the memory hungry deserialisation process and this, in turn creates large object that may throw an OutOfMemoryException due to fragmentation)

3) I have no clue why the space is fragmented, because when i look at the large object heap, there are only 30 instances, 15 object[] are directly attached to the GC and totally unrelated to me, 1 is a char array also attached directly to the GC Heap, the remaining 15 are mine but are not the cause of this as i get the same report if i comment them out in code.

So my question is, what can i do to go further with this? I'm not really sure what to look for in debugging / tools as it seems my memory is fragmented, but not by me, and huge amounts of free spaces are allocated by .net , which i can't release.

Also please make sure you understand the question well before answering, i'm not looking for a way to free memory within .net (GC.Collect), but to free memory that is already free in .net , to the system as well as to defragment said memory.

Note that a slow solution is fine, if it's possible to manually defragment the large heap i'd be all for it as i can call it at the end of RefreshCache and it's ok if it takes 1 or 2 second to run.

Thanks for your help!

A few notes i forgot: 1) The project is a .net 2.0 website, i get the same results running it in a .net 4 pool, idem if i run it in a .net 4 pool and convert it to .net 4 and recompile.

2) These are results of a release build, so debug build can not be the issue.

3) And this is probably quite important, i do not get these issues at all in the webdev server, only in IIS, in the webdev i get memory consumption rather close to my actual consumption (well more, but not 5-10X more!)

解决方案

Objects allocated on the large object heap (objects >= 85,000 bytes, normally arrays) are not compacted by the garbage collector. Microsoft decided that the cost of moving those objects around would be too high.

The recommendation is to reuse large objects if possible to avoid fragmentation on the managed heap and the VM space.

http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

I'm assuming that your large objects are temporary byte arrays created by your deserialization library. If the library allows you to supply your own byte arrays, you could preallocate them at the start of the program and then reuse them.

这篇关于.NET可用内存使用情况(如何防止OS释放内存/释放内存)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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