Tag: 垃圾收集

垃圾收集和引用C#

我有一个设计,我不确定垃圾收集是否会正确发生。 我有一些神奇的苹果,有些是美味的,有些是坏的。 我有一本字典: BasketList = Dictionary (篮子清单)。 每个Basket对象中都有一个Apple ,每个Basket存储一个对象AppleSeperation的引用。 AppleSeperation存储2个词典, YummyApples = 和BadApples = Dictionary ,所以当我被问到苹果在哪里时我知道。 Apple对象存储BasketsImIn = Dictionary ,它指向Basket和Shops,以及Apple in Basket。 我的问题是,如果我从BasketList删除一个篮子并确保从BadApples和/或YummyApples删除Apple, BadApples垃圾收集是否会正常发生,或者是否会出现一些混乱的引用?

垃圾收集孤立对象(树节点)适用于“release-exe”,但不适用于VS-debugger

情况 根据这个已接受的答案 ,如果“ GC”看到’2个或更多对象的循环引用,这些对象未被任何其他对象或永久GC句柄引用,则将收集这些对象。 我想知道垃圾收集是否适用于一个甚至没有内容的超级简单树结构,只是带有父级和子级引用的树节点。 想象一下,你创建一个根节点为它添加一个子节点,然后为子节点添加一个子节点等等,所以不是一个树,而是更像一个列表(每个节点最多只有一个子节点和一个父节点)。 如果我们理解上面的答案,然后我们删除了root的子节点以及该子节点内节点的所有引用,垃圾收集器应该清理子树。 问题描述 如果你看一下下面测试代码中的Main方法,当从Release-directory运行exe时,我得到的行为我预计内存消耗会增加到~1GB然后下降到~27MB(在1之后)。 GC.collect再次向上然后再降低到~27MB(对于2. GC.collect)。 现在当它在调试器中运行时,内存消耗达到~1GB,而1.GC.collect内存消耗保持精确到达1.6GB,第二个for循环需要时间,然后我最后在第二个for循环中得到一个OutOfMemoryException 。 问题 为什么我在调试器中会出现这种行为? 在调试期间不应该进行垃圾收集工作,我是否遗漏了一些关于调试器的信息? 旁注 我正在使用visual studio 2010 Express版 我只在这里调用GC.Collect()用于特定的测试目的,以确保应该进行垃圾收集。(我不打算正常使用它) using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Tree { class Program { static void Main(string[] args) { TreeNode root = new TreeNode(null); // the null-argument is the parent-node TreeNode node = […]

理解一次性物体

我已经看过像这样的问题,甚至我发现了很多,其中任何一个都为我提出了这个问题。 我们假设我有这个代码: public class SuperObject : IDisposable { public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { } } 我是否需要在SuperObject上使用protected virtual void Dispose(bool) ? 因为那里真的没有什么可以处理的。 public interface ICustom : IDisposable { } public class Custom : ICustom { public SuperObject Super { get; protected set; } public Custom() { Super = […]

为什么终结器中的AppDomain.Unload()错误?

这是一些示例代码: using System; namespace UnloadFromFinalizer { class Program { static void Main(string[] args) { Program p = new Program(); } AppDomain domain; Program() { this.domain = AppDomain.CreateDomain(“MyDomain”); } ~Program() { AppDomain.Unload(this.domain);//<– Exception thrown here } } } 我有一个类,它在构造函数中创建一个AppDomain,用于在对象的生命周期内使用。 我想正确清理AppDomain,所以我想我会在终结器中调用Unload。 不幸的是,这会导致抛出CannotUnloadAppDomainException。 AppDomain.Unload的MSDN文档说明: 在某些情况下,如果在终结器中调用,则调用Unload会导致立即的CannotUnloadAppDomainException。 为什么是这样? 是否已清除成员变量“domain”? 该清理是否自动包括卸载AppDomain,还是以某种无法访问的方式存在? 有什么我应该做的,或者我可以安全地转储终结器? (只要在此过程中完全清理了GC,我就不在乎GC何时清除了我的对象。)

GC根源误解?

我知道Roots是: 静态字段 方法参数 当地的fielfs f-queue还包含一个指向“即将被完成”的对象的指针 cpu寄存器<= ??? 现在让我们谈谈寄存器。 他们可以包含的代码如下: mov bx, 0034h ; bx = 52 (stored in 16 bits) mov cl, bl ; cl = lower 8-bits of bx mov eax, ecx call print_int 但是等等 ! 如果我没有弄错的话,这就是实际的代码,那就是从那里开始拿那些static , local和parameters ! 那么为什么写这个TWICE呢? (或从另一个方向?) 为什么要写(例如) Foo f = new Foo(); **and also** mov bx, 0034h //<——– […]

FileStream.Write()抛出OutOfMemoryException的可能原因?

我有10个线程将数千个小缓冲区(每个16-30个字节)写入随机位置的大文件中。 一些线程在FileStream.Write()opreation上抛出OutOfMemoryException。 导致OutOfMemoryException的原因是什么? 要找什么? 我正在使用像这样的FileStream(对于每个书面项目 – 此代码从10个不同的线程运行): using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.ReadWrite, BigBufferSizeInBytes, FileOptions.SequentialScan)) { … fs.Write(); } 我怀疑在FileStream中分配的所有缓冲区都不会被GC及时释放。 我不明白为什么CLR而不是抛出不只是运行GC循环并释放所有未使用的缓冲区?

在c#中查看垃圾收集历史记录(VS2015)

当我运行我的应用程序时,“进程内存”图中显示了无法预料和意外数量的垃圾收集活动,这让我想知道程序中生成的垃圾在哪里,因为我觉得我没有任何内存泄漏该程序。 有人可以告诉我是否有办法查看我的代码中生成垃圾的部分(或行)? 提前致谢。

防止非托管函数指针垃圾回收

将代理转换为非托管代码的文档说明我自己负责阻止代理收集。 我想知道在非管理呼叫是否有效的情况下是否无法收集代表。 例如,如果我这样做 UnmanagedFunction(arg => somebody); 其中UnmanagedFunction不存储超出其调用的函数指针。 这应该是合法的,对吧? 在UnmanagedFunction正在执行时,CLR无法收集。

每个用户定义的类是否需要实现IDisposable接口以获取垃圾

我不确定用户定义的类对象是如何被垃圾收集的。 我是否需要在每个类上实现IDisposable接口并调用dispose()方法来释放内存?

使用use来处理嵌套对象

如果我有这样的嵌套对象的代码,我是否需要使用嵌套的using语句来确保SQLCommand和SQLConnection对象都正确处理,如下所示,或者如果实例化SQLCommand的代码在外部使用声明。 using (var conn = new SqlConnection(sqlConnString)) { using (var cmd = new SqlCommand()) { cmd.CommandType = CommandType.Text; cmd.CommandText = cmdTextHere; conn.Open(); cmd.Connection = conn; rowsAffected = cmd.ExecuteNonQuery(); } }