为什么要打电话给GC.收集正在加快速度
Why calling GC.Collect is speeding things up
我们有一个C++库(没有MFC,没有ATL),它为我们的.NET应用程序提供了一些核心功能。SWIG 使用C++ DLL 生成可用于使用 PInvoke 访问其类/方法的 C# 程序集。此 C# 程序集在我们的 .NET 应用程序中用于使用 DLL C++中的功能。
该问题与内存泄漏有关。在我们的 .NET 应用程序中,我的 .NET 代码中有一个循环,该循环从C++ DLL 创建特定类的数千个实例。循环在创建实例时会不断变慢,但如果我调用 GC。循环中的 collect()(我知道不推荐这样做),处理速度变快。这是为什么呢?在类型上调用 Dispose() 对速度没有任何影响。我预计使用 GC 的程序速度会降低。Collect() 但它恰恰相反。
SWIG 生成的每个类都有一个调用 Dispose() 的 ~析构函数。每个 Dispose 方法在调用以释放非托管内存的语句周围都有一个锁 (this)。最后它调用 GC。抑制完成。我们还在发布版本中偶尔看到 AccessViolationException。任何帮助将不胜感激。
某些类型的对象可以在自己之后清理(通过Finalize
),如果它们被放弃而不被处置,但在终结器处理它们之前保留它们的成本可能很高; 框架中的一个例子是Microsoft.VisualBasic.Collection.GetEnumerator()
返回的枚举器。 每次调用GetEnumerator()
都会将新枚举器对象包装的对象附加到集合管理的各种私有更新事件中,当枚举器Dispose
d 时,它将取消订阅其事件。 如果在没有释放枚举器且没有干预垃圾回收的情况下多次调用GetEnumerator()
(例如数千或数百万次),则随着事件订阅列表的不断增长,收集将变得越来越慢(比正常情况慢数百或数千倍)。 但是,一旦发生垃圾收集,任何被遗弃的枚举器的Finalize
方法都将清理其订阅,并且事情将再次开始正常运行。
我知道你说过你正在调用Dispose
,但我怀疑某些东西正在创建一个IDisposable
对象实例而不是在其上调用Dispose
。 如果类Foo
创建并拥有IDisposable
类Bar
的实例,IDisposable
但Foo
不会在其自己的Dispose
实现中Dispose
该实例,则在Foo
实例上调用Dispose
不会清理Bar
。 一旦Foo
实例被放弃,无论它是否被Dispose
d,其Bar
最终都会被放弃而不被处置。
你叫GC吗?压制在您的处置方法中完成?无论如何,有很好的MSDN文章解释了如何编写GC友好代码 - 垃圾回收基础知识和性能提示。也许它会有用。
- 为什么在读取文件大小时文件IO速度会发生变化
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 文件系统:复制功能的速度秘诀是什么
- 学习多线程C++:添加线程不会使执行速度更快,即使它看起来应该
- 在C++中使用并行化的预期速度是多少(不是 OpenMp,而是 <thread>)
- 两个连续的 OpenMP 并行区域会相互减慢速度
- 查找标准::hash_map与标准::矢量的速度
- 加快在C++中读取/处理日志文件的速度
- 为什么这些算法的运行速度比它们应该的要快?
- 如何提高文件的读取速度?
- 通过libpqxx提高PostgreSQL数据库的更新速度
- 使用 IMFSinkWriter 编码的视频的播放速度会根据宽度而变化
- 计算车辆之间的距离并设置速度,使距离保持不变,例如 5 米
- 如何加快大字符串的解析速度?
- 如何比较两个函数的速度和性能
- 线程相互减慢速度
- 多线程减慢程序速度:无错误共享,无互斥锁,无缓存未命中,无小工作量
- 使用 Unity 构建加快C++构建速度,并减少标头依赖项
- 从 OpenCV 3 切换到 OpenCV 4 会导致网络摄像头以最大 5 fps 的速度录制,而不是通常的 30 f
- 为什么要打电话给GC.收集正在加快速度