如果我有以下代码:
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass = null;
Run Code Online (Sandbox Code Playgroud)
pClass会被垃圾收集吗?或者它会在它们发生的时候仍然停止发射?我是否需要执行以下操作才能进行垃圾回收?
MyClass pClass = new MyClass();
pClass.MyEvent += MyFunction;
pClass.MyEvent -= MyFunction;
pClass = null;
Run Code Online (Sandbox Code Playgroud) 如果我理解正确,.net运行时将始终在我之后清理.因此,如果我创建新对象并停止在我的代码中引用它们,运行时将清理这些对象并释放它们占用的内存.
既然这就是为什么一些对象需要有一个析构函数或dispose方法呢?当它们不再被引用时,运行时不会清理它们吗?
在我的工作中,我们遇到了OutOfMemoryExceptions的问题.我写了一段简单的代码来模仿一些行为,我最终得到了以下谜团.看看这个简单的代码,它在内存耗尽时会爆炸.
class Program
{
private static void Main()
{
List<byte[]> list = new List<byte[]>(200000);
int iter = 0;
try
{
for (;;iter++)
{
list.Add(new byte[10000]);
}
}
catch (OutOfMemoryException)
{
Console.WriteLine("Iterations: " + iter);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在我的机器上,它结束了
Iterations: 148008
然后我GC.Collect在每千次迭代后添加了对循环的调用:
//...
for (;;iter++)
{
list.Add(new byte[10000]);
if (iter % 1000 == 0)
GC.Collect();
}
//...
Run Code Online (Sandbox Code Playgroud)
并且惊喜:
Iterations: 172048
当我GC.Collect每10次迭代后调用时,我甚至得到了193716次循环.有两件奇怪的事情:
手动呼叫如何GC.Collect产生如此严重的影响(分配多达30%)?
当没有"丢失"参考时(我甚至预设了List的容量),GC可以收集什么?
UPDATE
我将这里的各种答案结合到一个新问题的"确定"答案中.
原始问题
在我的代码中,我有一个事件发布者,它在应用程序的整个生命周期中都存在(这里简化为基本要素):
public class Publisher
{
//ValueEventArgs<T> inherits from EventArgs
public event EventHandler<ValueEventArgs<bool>> EnabledChanged;
}
Run Code Online (Sandbox Code Playgroud)
因为这个发布者可以在所有地方使用,所以我对自己创建这个小帮助类非常满意,以避免在所有订阅者中重写处理代码:
public static class Linker
{
public static void Link(Publisher publisher, Control subscriber)
{
publisher.EnabledChanged += (s, e) => subscriber.Enabled = e.Value;
}
//(Non-lambda version, if you're not comfortable with lambdas)
public static void Link(Publisher publisher, Control subscriber)
{
publisher.EnabledChanged +=
delegate(object sender, ValueEventArgs<bool> e)
{
subscriber.Enabled = e.Value;
};
}
}
Run Code Online (Sandbox Code Playgroud)
它工作正常,直到我开始在较小的机器上使用它,当我偶尔开始:
System.ComponentModel.Win32Exception
Not enough storage is available to process …Run Code Online (Sandbox Code Playgroud) 我构建了一个快速程序,需要遍历一个巨大的日志文件(几百万条记录)并从内部找到各种各样的零碎.由于数据量如此巨大,我一直很想看看我的Windows任务管理器性能选项卡,看看有多少CPU和内存被使用.
程序成功获得结果后,CPU使用率明显下降.但是在看到我的内存使用率在执行期间缓慢上升到几千兆字节后,它保持不变.
我试图在我的函数结束时调用GC.Collect(),尝试将事物设置为null,尝试在发布模式下运行程序(我听说GC.Collect()可能无法正常工作,因为我希望它在调试中模式).
如果我关闭程序,内存使用量会下降,但我无法弄清楚为什么在应用程序生命周期内无法清理我的应用程序.在一天结束时,这是一个一次性的应用程序,但我只是想知道我错过了什么,即什么是持有所有这些记忆.
思考?
我一直在想如果有一种方法可以加速释放.NET中的内存.我正在用.NET创建一个游戏(只有托管代码),不需要重要的图形,但我仍然想要正确编写它,以免失去性能.
例如,为不再需要的对象分配空值是否有用?我在互联网上的一些样本中看到了这一点.