Tag: garbage collection

EF(entity framework)使用“使用”语句

我有一个关于MVC的项目。 我们为数据库交易选择了EF。 我们为BLL层创建了一些管理器。 我找到了很多例子,其中using “ using ”语句,即 public Item GetItem(long itemId) { using (var db = new MyEntities()) { return db.Items.Where(it => it.ItemId == itemId && !it.IsDeleted).FirstOrDefault(); } } 这里我们创建一个DBcontext MyEntities()的新实例。 我们使用“ using ”以“确保正确使用IDisposable对象”。 这只是我经理中的一种方法。 但我有十多个。 每当我从管理器调用任何方法时,我将使用“ using ”statemant并在内存中创建另一个DBcontext。 什么时候垃圾收集器(GC)会处理它们? 谁知道? 但是还有另一种使用管理器方法的方法。 我们创建一个全局变量: private readonly MyEntities db = new MyEntities(); 并且在没有“ using ”语句的每个方法中使用DBcontext。 方法看起来像这样: public […]

C#语言:垃圾收集,SuppressFinalize

我正在阅读“C#语言”,第4版,它讨论垃圾收集如下: “BILL WAGNER:以下规则是C#与其他托管环境之间的重要区别。 在应用程序终止之前,会调用析构函数的所有尚未被垃圾回收的对象,除非已经抑制了这种清理(例如,通过调用库方法GC.SuppressFinalize)。“ 所以我在这里有几个问题: Q1。 为什么.net与其他托管环境不同(我想这是暗示Java?)? 任何特定的设计问题? Q2。 调用GC.SuppressFinalize对象会发生什么? 我明白这意味着GC不会调用这些对象的终结器(析构函数),如果是这样,这些对象什么时候才会被破坏,以便分配的内存位返回堆? 否则会有内存泄漏?

什么时候是一个垃圾收集对象?

在c#中,当没有对象的引用时,对象会被垃圾回收。 假设是这种情况,是否会收集以下任何一种情况,或者垃圾收集器是否足够智能以丢弃它们? class Program { static void Main() { A a = new A(); ab = new B(); aba = a; a = null; } { class A { public B b; } class B { public A a; }

垃圾收集器C#,关于’清除’对象的问题

我读了一些关于垃圾收集的信息(它是如何工作的等等)。 我试着理解它是如何运作我的例子,但我认为我有问题。 我知道垃圾收集器运行时: 内存不足, 你调用GC.Collect()。 这是我的代码: public partial class Form1 : Form { public Testing _d; public Boolean _first = false; public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { if (!_first) { _d = new Testing(); int test = _d.DoSomething(“example”); } } private void button2_Click(object sender, EventArgs e) { _first = […]

.NET是否删除父类会将子项变为“垃圾”?

假设您有一个Collection ,并且您即将删除一个项目。 B的实例从A的实例引用,并引用C的实例,如第一张图所示: 图A http://sofzh.miximages.com/c%23/240wuqh.png 现在,由于有一个指向B的引用,因此毫无疑问该对象被“删除”或被垃圾收集。 它只是从集合中删除,就像这样,对吗? 图B http://sofzh.miximages.com/c%23/4uxnp3.png 现在,让我们有一个Collection具有与以前相同的引用层次结构,让我们删除A的实例。 图C http://sofzh.miximages.com/c%23/1zd93dt.png 如果没有其他对A引用,不仅它从集合中删除,它被标记为垃圾。 我对吗? 那么B和C呢? 它们是否也成为垃圾,除非B引用C实例,否则没有其他引用? 这是我所面临的简化。 我想从集合中删除一个A实例,我想确保B和C一起使用它。 在我不再收集A的地方,所有仍然活着的“孩子”对我来说都是memory leaks。 当我看到我制作的这些照片时,它似乎太愚蠢了。 但我的情况有点不那么微不足道 。 它看起来像这样: 图4 http://sofzh.miximages.com/c%23/2ymhlq0.png 在图片中,Model层为黄色,ViewModel层为绿色 ‘A ViewModel’类引用其A Model A Model有一个B Model实例的集合( B是A的子A ,在Model和ViewModel层中都是如此) 每个B Model “知道它的父亲” – 引用其父“模型”实例 回到VM层,’A ViewModel’拥有’B ViemModel’项目的集合 任何好的ViewModel,’B ViewModel’引用’B模型’ 我有一个A ViewModel实例的集合。 当我删除一个时,我需要其他所有内容。 如果所涉及的任何实例都没有其他“外部参考”(基本上,没有其他箭头指向图片外部),被移除的“ViewModel”实例是否会将所有孩子带走? 如果是这样,是否有任何“陷阱”可以使这种简化误导? 如果我完全错了,为什么? 🙂 感谢您阅读这篇文章!

为什么C#垃圾收集行为对于Release和Debug可执行文件有所不同?

让我们考虑以下简单程序: class Program { class TestClass { ~TestClass() { Console.WriteLine(“~TestClass()”); } } static void Main(string[] args) { WeakReference weakRef; { var obj = new TestClass(); weakRef = new WeakReference(obj); Console.WriteLine(“Leaving the block”); } Console.WriteLine(“GC.Collect()”); GC.Collect(); System.Threading.Thread.Sleep(1000); Console.WriteLine(“weakRef.IsAlive == {0}”, weakRef.IsAlive); Console.WriteLine(“Leaving the program”); } } 在Release模式下构建时,可预测打印: Leaving the block GC.Collect() ~TestClass() weakRef.IsAlive == False Leaving […]

为什么耗尽内存取决于对GC.GetTotalMemory的中间调用?

我编写的内存密集型程序内存不足:抛出OutOfMemoryexception。 在尝试减少内存使用量的过程中,我开始调用GC.GetTotalMemory(true)(将总内存使用量写入调试文件),这会触发垃圾收集。 出于某种原因,当调用此函数时,我不会再出现内存不足的exception。 如果我再次删除调用(保持其他所有内容相同),则会再次抛出exception。 根据我的理解,当内存压力增加时,会自动调用来收集垃圾,所以我不明白这种行为。 任何人都可以解释为什么只有在没有GC.collect调用时才抛出内存不足exception? 更新: 我正在使用VS 2010,但我正在将应用程序转移到框架3.5。 我相信碎片整理确实会导致我的问题。 我做了一些测试:当抛出exception时,对GC.gettotalmemory的调用告诉我我正在使用~800 * 10 ^ 6个字节。 但是,任务管理器告诉我应用程序使用的是1700 mb。 一个相当大的差异。 我现在计划只分配一次内存,并且永远不会释放任何大型数组但重用它们。 幸运的是,我的程序让我可以毫不费力地完成这个任务。

防止所有者垃圾收集的线程

在我创建的库中,我有一个类DataPort,它实现类似于.NET SerialPort类的function。 它与某些硬件进行通信,并且只要数据通过该硬件进入就会引发事件。 为了实现此行为,DataPort会旋转一个预期与DataPort对象具有相同生命周期的线程。 问题是当DataPort超出范围时,它永远不会被垃圾收集 现在,因为DataPort与硬件(使用pInvoke)对话并拥有一些非托管资源,所以它实现了IDisposable。 当您在对象上调用Dispose时,一切都正常。 DataPort摆脱了所有非托管资源并杀死了工作线程并消失了。 但是,如果您只是让DataPort超出范围,垃圾收集器将永远不会调用终结器,并且DataPort将永远保留在内存中。 我知道这种情况有两个原因: 终结器中的断点永远不会被击中 SOS.dll告诉我DataPort仍然存在 补充:在我们继续前进之前,我会说是的,我知道答案是“Call Dispose()Dummy!” 但我认为,即使你让所有引用超出范围, 最终应该发生正确的事情,垃圾收集器应该摆脱DataPort 回到问题:使用SOS.dll,我可以看到我的DataPort没有被垃圾回收的原因是因为它旋转的线程仍然具有对DataPort对象的引用 – 通过隐含的“this”参数线程正在运行的实例方法。 正在运行的工作线程不会被垃圾回收 ,因此在正在运行的工作线程范围内的任何引用也不符合垃圾回收的条件。 线程本身基本上运行以下代码: public void WorkerThreadMethod(object unused) { ManualResetEvent dataReady = pInvoke_SubcribeToEvent(this.nativeHardwareHandle); for(;;) { //Wait here until we have data, or we got a signal to terminate the thread because we’re being disposed int signalIndex = […]

在C#中使用Finalizer的好样本

当我在C#中阅读一些关于内存管理的文章时,我对Finalizer方法感到困惑。 有许多与之相关的复杂规则。 例如,没有人知道终结器何时被调用,即使ctor中的代码抛出,他们也会调用,CLR不保证在程序关闭时调用所有终结器等。 对于什么终结器可以在现实生活中使用? 我发现的唯一一个例子是程序在GC启动时发出蜂鸣声。 您是否在代码中使用了Finalizer并且可能有一些好样本? UPD: 当开发人员想要确保某些类始终通过IDisposable正确处理时,可以使用终结器。 ( 链接 ;感谢Steve Townsend )

GC.KeepAlive与使用

在他关于防止应用程序的多个实例的文章中 ,Michael Covington提出了以下代码: static void Main() // args are OK here, of course { bool ok; m = new System.Threading.Mutex(true, “YourNameHere”, out ok); if (! ok) { MessageBox.Show(“Another instance is already running.”); return; } Application.Run(new Form1()); // or whatever was there GC.KeepAlive(m); // important! } 他解释说,GC.KeepAlive(m)是防止垃圾收集器尽早收集互斥锁所必需的,因为没有额外的引用。 我的问题:将使用互斥锁包装做同样的事情吗? 也就是说,以下是否也会阻止GC从我身下拉出地毯? static void Main() // args are OK […]