在你报告我提出一个常见问题之前,请听我说。
我正在编写一个程序,使用C#和Windows窗体从数据记录器中读取。每个通道可以表示不同的事物,例如升力,阻力和压力。我打算让这些频道可配置。以下是这种频道的初始化方式:
private Channel Lift_Channel = new Channel(1);
这会将Lift_Channel初始化为引用记录器上通道1的Channel对象。
但是,构造函数方法Channel(int)是我可用于设置通道的唯一方法。如果我想要Lift_Channel指向频道2,我想做这样的事情。
delete Lift_Channel;
Lift_Channel = new Channel(2);
我觉得如果我不能删除Lift_Channel然后重新创建它,我会有内存泄漏错误,因为Channel(1)数据会浮动。
有什么想法吗?
答案 0 :(得分:4)
在C ++中,必须删除在堆上分配的任何对象,否则它将泄漏内存。在仅使用托管代码的典型.NET托管应用程序中,开发人员不必担心在使用托管代码时删除对象。这是因为.NET有一个非常好用和高效的垃圾收集器。它跟踪对象的所有引用,并且当对象的最后一个引用不再有效时,它会自行删除该对象。垃圾收集器通常与内存页面错误大致同时运行,因此非常有效。
如果对象使用非托管代码,有时可能需要实现一些代码来处理清理对象。 .NET为此提供了一个名为IDisposable的接口。这背后的主要思想是实例化对象的代码调用Dispose方法来执行清理。如果有人忘记这样做,那么垃圾收集器最终会将你的终结器方法称为故障安全。终结器需要实现对Dispose方法的调用。上面的链接显示了这方面的一个例子。
垃圾收集器(GC)在后台自动运行,并在进行任何清理工作之前停止所有活动的托管线程。这项清理工作的一部分涉及压缩内存,它可以移动内存。如果您调用了使用指针或对托管数据的引用的非托管代码,那么该数据应该固定在内存中,以便GC不会移动它。这可以使用Fixed语句在给定方法中使用,或GCHandle.Alloc方法可以在更长的时间段内使用,可以在声明的方法之外使用.GCHandle Free方法应该是打电话来释放别针。固定内存需要将代码标记为不安全。
.NET提供了一个名为GC的类,可用于帮助控制垃圾收集器。例如,如果您有使用大量内存的对象并且希望在继续之前等待释放内存,那么在将它们设置为null之后,应该调用以下方法来完成此操作:
GC.Collect();
GC.WaitForPendingFinalizers();
答案 1 :(得分:3)
不,没有删除。重新分配后,Lift_Channel将不再指向旧的内存地址,内存将被清除。
答案 2 :(得分:1)
.Net垃圾收集无法再访问的已分配项目。采集。垃圾收集器定期运行,并将回收其他任何内容无法访问的对象的内存。
通过新的new
分配,以前与变量相关联的存储器(在重新分配之前)将不再可达(假设变量是唯一引用它的变量)。因此旧的对象变得无法访问,然后垃圾收集器将在下次运行时将其拾取。
因此,没有delete
运营商。
所有这些操作都实现了删除的效果。 (最后,如果项目无法访问,则在垃圾收集器运行时将删除它。)