Tag: 垃圾收集

如何从多个托管应用程序的大对象堆LOH中取回未使用的内存?

在与同事谈论启动时使用近1.5G内存的特定应用程序组时…他指出了一个关于.NET生产调试的非常好的链接 困惑的部分是…… 例如,如果为单个块分配1 MB内存,则大对象堆的大小​​将扩展为1 MB。 释放此对象时,大对象堆不会解除对虚拟内存的影响,因此堆的大小保持为1 MB。 如果稍后再分配另一个500 KB块,则新块将在属于大对象堆的1 MB内存块中分配。 在进程生命周期中,大对象堆总是增长以保存当前引用的所有大块分配,但是在释放对象时从不收缩,即使发生了垃圾收集。 下一页的图2.4显示了一个大对象堆的示例。 现在让我们假设我们有一个虚构的应用程序,可以创建一大堆大对象(> 85KB),所以大对象堆增长让我们说200 Meg。 现在假设我们有10个这样的app实例正在运行..所以分配了2000 Megs。 现在这个记忆永远不会回到操作系统,直到过程关闭……(就是我所理解的) 我的理解是否有任何差距? 我们如何在各种LOHeaps中找回未使用的内存; 我们不创造OutOfMemoryExceptions的完美风暴? 更新:从Marc的回复中,我想澄清LOH对象没有被引用 – 大对象是use-n-throw – 但是即使堆在初始激增之后堆相对空,堆也不会收缩。 更新#2:只是包含一个代码片段(夸大但我觉得有点了)..我看到一个OutOfMemoryException,虚拟内存在我的机器上达到1.5G标记(1.7G在另一个上)…来自Eric L 。博客文章 ,’进程内存可以被视为磁盘上的大量文件……’ – 因此这个结果是出乎意料的。 在这种情况下,机器在HDD上具有GB的可用空间。 PageFile.sys OS文件(或相关设置)是否施加了任何限制? static float _megaBytes; static readonly int BYTES_IN_MB = 1024*1024; static void BigBite() { try { var list = new List(); […]

垃圾收集器是在单独的进程中运行的吗?

垃圾收集器是否在单独的进程中启动? 例如: 如果我们尝试测量某些代码所花费的处理时间,并且在此过程中垃圾收集器开始收集,它将在新进程或同一进程中启动吗? 它的工作方式如下吗? //Code (Process 1) –> Garbage Collector Run (Process 1) //Code (Process 1) 或者像这样? //Code (Process 1) –> Garbage Collector Run (Process 2) //Code (Process 1)

任务完成后C#不释放内存

以下代码是我看到的问题的简化示例。 由于字典太大,此应用程序在抛出exception之前会占用大约4GB的内存。 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 aMassiveList = new Dictionary(); try { long i […]

允许迭代而不产生任何垃圾

我在实现IEnumerable接口的对象池中有以下代码。 public IEnumerable ActiveNodes { get { for (int i = 0; i < _pool.Count; i++) { if (_pool[i].AvailableInPool) { yield return _pool[i]; } } } } 据我所知(根据这个问题),这将产生垃圾,因为需要收集IEnumerable对象。 _pool中的所有元素都不会被收集,因为池的目的是保持对所有元素的引用以防止垃圾创建。 任何人都可以建议一种允许迭代_pool的方法,以便不生成垃圾? 在池上迭代时,池中具有AvailableInPool == true所有项都应该迭代。 订单无关紧要。

.NET垃圾收集器之谜

在我的工作中,我们遇到了OutOfMemoryExceptions的问题。 我写了一段简单的代码来模仿一些行为,我最终得到了以下谜团。 看看这个简单的代码,当内存耗尽时会爆炸。 class Program { private static void Main() { List list = new List(200000); int iter = 0; try { for (;;iter++) { list.Add(new byte[10000]); } } catch (OutOfMemoryException) { Console.WriteLine(“Iterations: ” + iter); } } } 在我的机器上它结束了 Iterations: 148008 然后我在每千次迭代后添加了一个GC.Collect调用循环: //… for (;;iter++) { list.Add(new byte[10000]); if (iter % 1000 == 0) […]

事件触发前的对象处理和垃圾收集

一段代码由我正在与之交谈的人提出: private void DownloadInformation(string id) { using (WebClient wc = new WebClient()) { wc.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadStringCompleted); wc.DownloadStringAsync(new Uri(“http://www.fake.com/” + id)); } } 以上是此简化版: (我已获得作者的许可发布图片。) 令我烦恼的是,该代码附带了一个事件处理程序,调用了DownloadStringAsync() ,然后using结束,在WebClient上调用了Dispose() 。 在DownloadStringAsync()完成和DownloadStringCompleted事件触发之前,是否有任何东西会阻止WebClient被using甚至垃圾收集掉? 有一个更新的方法, DownloadStringTaskAsync() ,我认为它与await一起使用: private async Task DownloadInformation(string id) { using (WebClient wc = new WebClient()) { wc.DownloadStringCompleted += DownloadStringCompleted; await wc.DownloadStringTaskAsync(new Uri(“http://www.fake.com/” + id)); } } […]

在.NET中集合中的WeakReferences的最佳时间

我有一个集合(我正在写一个弱字典 ),我需要定期剔除死的WeakReferences。 我经常看到的是检查添加和删除方法,即“在对集合进行X修改之后,是时候剔除了”。 这对我来说是可以接受的,但似乎应该有更好的方法。 我真的很想知道GC何时运行并立即运行我的清理代码。 毕竟,GC可能是确定何时是清理死引用的好时机的最佳机制。 我发现垃圾收集通知 ,但看起来这不是我想要的。 我不想生成一个单独的线程来监视GC。 理想情况下,我的集合将实现IWantToRunCodeDuringGC或订阅System.GC.Collected事件。 但.NET框架可能无法信任用户代码在GC期间运行… 或者也许还有另一种我忽视的方法。 编辑:如果我的代码在GC之后,之前或期间运行,我认为这并不重要。

BinaryReader.Dispose(bool disposing)创建一个对stream的本地引用。 为什么?

我在FCL代码中发现了一个不寻常的样本。 这是System.IO.BinaryReader中的方法: protected virtual void Dispose(bool disposing) { if (disposing) { Stream copyOfStream = m_stream; m_stream = null; if (copyOfStream != null && !m_leaveOpen) copyOfStream.Close(); } m_stream = null; m_buffer = null; m_decoder = null; m_charBytes = null; m_singleChar = null; m_charBuffer = null; } “copyOfStream”对执行逻辑有什么影响?

分配给事件的lambda会阻止拥有对象的垃圾收集吗?

假设您有一个带有事件属性的类。 如果在本地上下文中实例化此类,而没有外部引用,则会为事件分配lambda表达式,以防止实例被垃圾回收? { var o = new MyClass(); o.MyClassEvent += (args) => {}; } // Will ‘o’ be eligible for garbage collection here?

在处理类实例时,是否需要显式处理其所有IDisposable成员?

我有一个类,它具有SqlConnection类型的属性。 SqlConnection实现了IDisposable 。 我有以下问题: 我的类是否也应该实现IDisposable ,因为它具有IDisposable类型的属性? 如果是,我在处理类的实例时是否需要显式处理属性? 例如 public class Helper : IDisposable { // Assume that it’s ANY OTHER IDisposable type. SqlConnection is just an example. public SqlConnection SqlConnection { get; set; } public void Dispose() { if (SqlConnection!= null) { SqlConnection.Dispose(); } } } 注意:我知道在实现IDisposable需要遵循一个模式,但我的问题非常具体到上面提到的情况。