Tag: garbage collection

如何在C#/ MVVM应用程序中解决无法解释的ObjectDisposedExceptions?

我编写了我的第一个MVVM应用程序。 当我关闭应用程序时,我常常因ObjectDisposedException而导致崩溃。 应用程序窗口消失后,应用程序即会崩溃。 获取堆栈跟踪很困难( 参见我的另一个问题 ),但最后我做了,发现我的堆栈跟踪完全包含在C#库中(kernel32!BaseThreadStart,mscorwks!Thread,mscorwks!WKS等)。 此外,这次崩溃是不一致的。 在我上次结账和重建之后,它停止了一段时间。 然后它又回来了。 一旦它开始发生,它就会不断发生, 即使我“清理”并重建 。 但擦拭和结账有时会使其停止一段时间。 我认为发生了什么: 我认为GarbageCollector在处理我的ViewModel时做的很有趣。 我的ViewModelBase类析构函数在调用析构函数时有一个WriteLine来记录,而在我的4个ViewModel中,只有2或3个被处理掉了,它似乎根据结帐而变化(例如,当我在我的运行时,我看到一直在重复顺序,但我的同事看到不同的序列与不同的对象处置)。 由于堆栈跟踪没有我的代码调用,我认为这意味着我的代码不是调用被处置对象的方法。 所以这让我觉得CLR是愚蠢的。 这有意义吗? 有什么方法可以让GC保持一致吗? 这是红鲱鱼吗? 其他可能有用的细节: 我的所有Views和ViewModel都是在App.xaml.cs文件的Application的Startup事件处理程序中创建的。 同一个处理程序将ViewModels分配给DataContexts。 我不确定这是否是正确的MVVM实践(正如我所说的,我的第一个MVVM应用程序),但我不明白为什么它会导致不良行为。 如有必要,我可以粘贴代码。

跨C#和C ++ / CLI对象的垃圾收集

我目前正在研究使用C ++ / CLI来弥补托管C#和本机非托管C ++代码之间的差距。 我想要解决的一个特殊问题是C#和C ++中不同的数据类型的转换。 在阅读使用这种桥接方法以及所涉及的性能影响的同时,我想知道垃圾收集如何工作。 具体来说,如果垃圾收集器在“另一侧”被引用/销毁,它们将如何处理在任一侧创建的对象的清理。 到目前为止,我已经阅读了有关StackOverflow和MSDN的各种文章和论坛问题,这让我相信垃圾收集器在同一个进程中运行时应该跨两种类型的代码工作 – 即如果一个对象是用C#创建的,传递给C ++ / CLI桥接器,在双方的引用不再使用之前不会收集它。 在这种情况下,我的问题分为三个部分: 我是否正确地得出结论,当在同一个进程中运行时,垃圾收集器可以跨代码的两个部分(C#和C ++ / CLI)工作? 关于1:在这种情况下它是如何工作的(特别是在清理两个代码库引用的对象方面)。 是否有关于如何监视垃圾收集器活动的建议 – 即编写测试以检查垃圾收集何时发生; 或监视垃圾收集器本身的程序。 我已经对垃圾收集器的工作原理有了一些了解,所以我的问题特定于以下场景: 组件 大会A – (用C#编写) 程序集B – (用C ++ / CLI编写) 程序执行 对象O在程序集A中创建。 对象O被传递到Assembly B内的一个函数中。 已发布对程序集A中对象O引用。 程序集B保持对对象O引用。 执行结束(即通过程序退出)。 程序集B释放对象O引用。 提前感谢您对此问题的任何想法。 如果需要进一步的信息或者某些内容不够清楚,请告诉我。 编辑 根据要求,我已经写了一个我想要描述的场景的粗略示例。 可以在PasteBin上找到C#和C ++ / CLI代码。

.NET垃圾收集行为(使用DataTable obj)

我想知道为什么在创建一个非常简单的DataTable然后将其设置为null后,垃圾收集不会清除该DataTable使用的所有内存。 这是一个例子。 变量Before应该等于Removed但它不是。 { long Before = 0, After = 0, Removed = 0, Collected = 0; Before = GC.GetTotalMemory(true); DataTable dt = GetSomeDataTableFromSql(); After = GC.GetTotalMemory(true); dt = null; Removed = GC.GetTotalMemory(true); GC.Collect(); Collected = GC.GetTotalMemory(true); } 给出以下结果。 Before = 388116 After = 731248 Removed = 530176 Collected = 530176

嵌套的固定语句

根据fixed语句的C# 引用 : fixed语句阻止垃圾收集器重定位可移动变量。 … 执行语句中的代码后,将取消固定任何固定变量并进行垃圾回收。 因此,不要指向固定语句之外的那些变量。 我的问题是,如果我们为同一个变量嵌套了fixed语句,那么我在这个页面上找不到的内容是什么? var data = new byte[100]; unsafe { fixed(byte* pData = data) { //pData points to the “pinned” variable fixed(byte* pData2 = data) { //pData points to the “pinned” variable //pData2 points to the “pinned” variable } //Does pData still point to the “pinned” variable? } } 上面的代码当然只是为了说明。 […]

如何避免长寿命字符串导致第2代垃圾收集

我有一个应用程序,我将日志字符串保存在循环缓冲区中。 当日志变满时,对于每个新插入,旧的字符串将被释放用于垃圾收集,然后它们在第2代内存中。 因此,最终将发生第2代GC,我想避免。 我试图将字符串编组成一个结构。 令人惊讶的是,我仍然得到第2代GC:s。 结构似乎仍然保留了对字符串的一些引用。 完整控制台应用程序 任何帮助赞赏。 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication { class Program { [StructLayout(LayoutKind.Sequential)] public struct FixedString { [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] private string str; public FixedString(string str) { this.str = str; } } [StructLayout(LayoutKind.Sequential)] public struct UTF8PackedString { private […]

我是否需要保留对FileSystemWatcher的引用?

我正在使用FileSystemWatcher (在ASP.NET Web应用程序中)监视文件以进行更改。 观察者在Singleton类的构造函数中设置,例如: private SingletonConstructor() { var fileToWatch = “{absolute path to file}”; var fsw = new FileSystemWatcher( Path.GetDirectoryName(fileToWatch), Path.GetFileName(fileToWatch)); fsw.Changed += OnFileChanged; fsw.EnableRaisingEvents = true; } private void OnFileChanged(object sender, FileSystemEventArgs e) { // process file… } 到目前为止一切正常。 但我的问题是: 使用局部变量( var fsw )设置观察者是否安全? 或者我应该在私人领域中保留它的引用,以防止它被垃圾收集?

使用对话框表单周围的语句来确保垃圾回收

我们有一个包含数千个表单的Windows窗体应用程序。 其中许多通过ShowDialog()方法临时显示为对话框。 这个应用程序已存在多年,我们发现由于表单中的各种资源泄漏或它使用的控件,许多表单没有及时收集垃圾。 具体来说,我们已经找到了未正确处理的GDI +资源的示例,尽管可能存在尚未表征的其他类型的资源泄漏。 虽然解决这个问题的正确方法显然是要经历每一种forms和每一种控制,并消除所有的资源问题。 这需要一些时间来完成。 作为一个短期的替代方案,我们发现在表单上显式调用Dispose()似乎启动了垃圾收集过程,并且表单及其资源立即被释放。 我的问题是,在一个using语句中包装每个表单的ShowDialog()块是否是一个合理的解决方法,以便在显示表单后调用Dispose(),这也是一个很好的做法吗? 例如,从以下位置更改现有代码: public void ShowMyForm() { MyForm myForm = new MyForm(); myForm.ShowDialog(); } 对此: public void ShowMyForm() { using (MyForm myForm = new MyForm()) { myForm.ShowDialog(); } } 在我们的测试中,第一个示例永远不会调用MyForm的Dispose()方法,但第二个示例会立即调用它。 当我们花时间追踪每个特定的资源问题时,这似乎是一种合理的方法作为短期解决方法吗? 我们是否可以考虑采用其他方法来确定和解决这些类型的资源问题的短期解决方法和/或方法?

在循环图中使用ThreadLocal 时内存泄漏

我刚刚遇到了垃圾收集器关于System.Threading.ThreadLocal这种奇怪的“行为”,我无法解释。 在正常情况下, ThreadLocal实例在超出范围时将被垃圾收集,即使它们没有正确处理,除非它们是循环对象图的一部分。 以下示例演示了此问题: public class Program { public class B { public AA; } public class A { public ThreadLocal LocalB; } private static List references = new List(); static void Main(string[] args) { for (var i = 0; i c.IsAlive)); } static void CreateGraph() { var a = new A { LocalB = […]

有什么方法可以解决C#中的内存泄漏问题

我正在学习C#。 据我所知,您必须正确设置以使垃圾收集器实际删除所有内容。 我正在寻找多年来从你那里学到的智慧,聪明。 我来自C ++背景,非常习惯代码气味和开发模式。 我想知道C#中的代码气味是什么样的。 给我建议! 删除内容的最佳方法是什么? 当你遇到“内存泄漏”时,你怎么能弄明白? 编辑:我正在尝试开发一个“总是为内存管理做的事情”的列表 非常感谢。

抑制C#垃圾回收

我的应用程序分配了大量内存(数百万个小对象,总计几千兆字节)并长时间保留它。 .NET是否在浪费时间检查所有这些数据以对其进行GC操作? Gen 2 GC多久出现一次(检查所有对象的那个)? 有没有办法降低它的频率或暂时抑制它的发生? 我确切地知道当我准备好收集大量内存时,有什么方法可以优化它吗? 我目前正在调用GC.Collect(); GC.WaitForPendingFinalizers(); 那时候。 更新:Perf计数器“GC中的%时间”显示平均值为10.6%。