|
|
1
164
如果你有充分的理由相信,一组重要的对象,特别是那些你怀疑属于第1代和第2代的对象,现在有资格进行垃圾收集,从性能影响的角度来看,现在是收集垃圾的合适时机。 一个很好的例子是,如果你刚刚关闭了一个大型窗体。你知道现在所有的UI控件都可以被垃圾回收,并且窗体关闭时的短暂停顿可能不会被用户注意到。 2018年7月更新
截至。NET 4.5-有
截至。NET 4.6-有
来源:微软工程师本·沃森: 写高性能。NET代码 ,2018年第2版。 请参阅: |
|
|
2
53
我用
因此
一个经典的例子是一个简单的控制台exe(A
如果我需要一些精确的东西,那么这将是两个完全独立的测试——但如果我们只是想在测试期间最小化(或规范化)GC以大致了解行为,这通常就足够了。 生产代码期间?我还没有使用它;p |
|
|
3
29
最好的做法是在大多数情况下不要强制垃圾收集。 (我研究过的每个强制垃圾收集的系统,都有强调的问题,如果解决了这些问题,就不需要强制垃圾收集,并大大加快了系统的速度。) 有一个 少数病例 什么时候 你 比垃圾收集器更了解内存使用情况。在多用户应用程序或一次响应多个请求的服务中,这不太可能是真的。 然而,在一些 批量处理 你知道的比GC多。例如,考虑一个应用程序。
你 五月 能够(在仔细测试后)证明,在处理每个文件后,应该强制进行完全垃圾收集。 另一种情况是,每隔几分钟就会唤醒一次服务来处理一些项目 在睡眠时不保持任何状态 。然后在睡觉前强制收集全部物品 五月 值得。
我宁愿有一个垃圾回收API,当我可以给它提示这种类型的事情,而不必强迫我自己GC。 另见“ Rico Mariani's Performance Tidbits " 这些天,我认为在上述情况下,最好使用一个短期的工作进程来完成每一批工作,并让操作系统进行资源恢复。 |
|
|
4
20
一种情况是,当您试图使用以下代码进行单元测试时 WeakReference . |
|
|
5
13
在大型24/7或24/6系统中——对消息、RPC请求做出反应或连续轮询数据库或进程的系统——有一种方法来识别内存泄漏是有用的。为此,我倾向于在应用程序中添加一种机制,暂时暂停任何处理,然后执行完全垃圾收集。这会使系统进入静态,其中剩余的内存要么是合法的长寿命内存(缓存、配置等),要么是“泄漏”的(不期望或不希望被根化但实际上被根化的对象)。 拥有这种机制可以更容易地分析内存使用情况,因为报告不会被活动处理的噪音所掩盖。 为了确保你得到所有的垃圾,你需要执行两次收集:
因为第一次收集将导致任何具有终结器的对象被终结(但实际上不会对这些对象进行垃圾收集)。第二个GC将对这些最终确定的对象进行垃圾收集。 |
|
|
6
12
你可以打电话
作为作者,人们往往倾向于认为这是可能的或正常的。然而,事实是GC相当于一个编写良好、经过测试的专家系统,你很少会知道它不知道的低级代码路径。 我能想到的最好的例子是,你可能有一些额外的信息,一个在空闲期和非常繁忙期之间循环的应用程序。您希望在繁忙时段获得最佳性能,因此希望利用空闲时间进行一些清理。 然而,大多数时候GC足够聪明,无论如何都能做到这一点。 |
|
|
7
8
一个几乎需要调用GC的实例。Collect()是指通过Interop自动化Microsoft Office。Office的COM对象不喜欢自动释放,这可能会导致Office产品的实例占用大量内存。我不确定这是一个问题还是设计问题。互联网上有很多关于这个话题的帖子,所以我不会详细介绍。 当使用Interop进行编程时, 每一个 COM对象应该手动释放,通常使用Marshal。ReleseComObject()。此外,手动调用垃圾回收可以帮助“清理”一点。在处理完Interop对象后调用以下代码似乎有很大帮助:
根据我的个人经验,结合使用ReleaseComObject和手动调用垃圾回收 非常 减少Office产品(特别是Excel)的内存使用。 |
|
|
8
8
作为内存碎片解决方案。 在将大量数据写入内存流(从网络流读取)时,我遇到了内存不足的异常。数据以8K块的形式写入。在达到128M后,即使有很多可用内存(但内存是碎片化的),也会出现异常。呼叫GC。Collect()解决了这个问题。修复后,我能够处理超过1G的数据。 |
|
|
9
7
看看Rico Mariani的这篇文章。他给出了两条何时给GC打电话的规则。收集(规则1是:“不要”): |
|
|
10
7
我正在对数组和列表进行性能测试:
我得到了
|
|
|
11
4
你应该尽量避免使用GC。Collect()因为它很贵。以下是一个示例:
测试结果:CPU使用率12% 当您更改为以下内容时:
测试结果:CPU使用率2-3% |
|
|
12
4
在你的例子中,我认为是调用GC。收藏不是问题,而是设计问题。 如果你要每隔一段时间(设定时间)醒来,那么你的程序应该为单次执行而精心设计(执行一次任务),然后终止。然后,将程序设置为按计划时间间隔运行的计划任务。 这样,你就不用担心给GC打电话了。收集(你应该 很少 如果有的话,必须这样做)。 话虽如此,Rico Mariani在这个主题上有一篇很棒的博客文章,可以在这里找到: |
|
|
13
3
一个有用的地方叫GC。Collect()是在单元测试中,当你想验证你没有创建内存泄漏时(例如,如果你正在使用WeakReferences或ConditionalWeakTable、动态生成的代码等做某事)。 例如,我有一些测试,比如:
可以说,使用WeakReferences本身就是一个问题,但似乎如果你正在创建一个依赖于这种行为的系统,那么就调用GC。Collect()是验证此类代码的好方法。 |
|
|
14
3
在某些情况下,安全总比后悔好。 这里有一种情况。 可以编写一个 非受管的 C#中的DLL使用IL重写(因为在某些情况下这是必要的)。 现在假设,例如,DLL在类级别创建了一个字节数组,因为许多导出的函数都需要访问这样的数组。卸载DLL时会发生什么?此时是否会自动调用垃圾收集器?我不知道,但作为一个 非受管的 DLL完全有可能没有调用GC。如果它不被调用,那将是一个大问题。当DLL被卸载时,垃圾收集器也会被卸载——那么谁将负责收集任何可能的垃圾,他们将如何做到这一点?最好使用C#的垃圾收集器。有一个清理函数(可用于DLL客户端),其中类级变量设置为null,并调用垃圾收集器。 安全总比后悔好。 |
|
|
15
3
如果你正在创造很多新的
|
|
|
16
2
简短的回答是:永远不会! |
|
|
17
2
|
|
|
18
2
另一个原因是当您在USB COM端口上打开SerialPort,然后拔下USB设备时。由于SerialPort已打开,资源在系统注册表中保存了对以前连接的端口的引用。然后,系统的注册表将 contain stale data ,因此可用端口列表将是错误的。因此,必须关闭港口。 正在调用串行端口。端口上的Close()调用对象上的Dispose(),但它会一直保留在内存中,直到垃圾回收器实际运行,导致注册表保持陈旧,直到垃圾收集器决定释放资源。 来自 https://stackoverflow.com/a/58810699/8685342 :
|
|
|
19
1
我对此仍然很不确定。 我在应用服务器上工作了7年。我们更大的安装使用24GB Ram。它具有高度的多线程性,并且所有调用都需要GC。Collect()遇到了非常糟糕的性能问题。 许多第三方组件使用GC。Collect(),当时他们认为现在这样做很聪明。 因此,一堆简单的Excel报告每分钟多次阻止所有线程的App Server。 为了删除GC,我们不得不重构所有第三方组件。Collect()调用,执行此操作后一切正常。 但我也在Win32上运行服务器,在这里我开始大量使用GC。在收到OutOfMemoryException后收集()。 但我对此也很不确定,因为我经常注意到,当我在32位上遇到OOM时,我会再次尝试运行相同的操作,而不调用GC。Collect(),它运行得很好。 我想知道的一件事是OOM异常本身。.. 如果我写的话。Net Framework,我不能分配内存块,我会使用GC。Collect(),对内存进行碎片整理(??),再试一次,如果我仍然找不到空闲内存块,那么我会抛出OOM异常。 或者至少将此行为设置为可配置选项,因为GC存在性能问题的缺点。收集。 现在,我的应用程序中有很多这样的代码来“解决”这个问题:
(请注意,Thread.Sleep()行为是一个真正特定于应用程序的行为,因为我们正在运行一个ORM缓存服务,如果RAM超过一些预定义值,该服务需要一些时间来释放所有缓存的对象。因此,它第一次等待几秒钟,每次发生OOM都会增加等待时间。) |
|
|
20
1
调用GC的一个很好的理由是在内存很少的小型ARM计算机上,比如Raspberry PI(使用mono运行)。 如果未分配的内存碎片占用了太多的系统RAM,那么Linux操作系统可能会变得不稳定。 我有一个应用程序,我必须每秒(!)调用GC来解决内存溢出问题。 另一个好的解决方案是在不再需要时处理对象。不幸的是,在许多情况下,这并不容易。 |
|
|
21
0
这与问题无关,但与XSLT转换有关。NET(XSLCompiledTranform),那么您可能别无选择。另一个候选者是MSHTML对照。 |
|
|
22
0
如果您使用的.net版本低于4.5,则手动收集可能是不可避免的(特别是当您处理许多“大型对象”时)。 此链接描述了原因: https://blogs.msdn.microsoft.com/dotnet/2011/10/03/large-object-heap-improvements-in-net-4-5/ |
|
|
23
0
因为有小对象堆(SOH)和大对象堆(LOH) 我们可以打电话给GC。Collect()清除SOP中的去引用对象,并将活动对象移动到下一代。 在.net4.5中,我们还可以通过使用 largeobjectheapcompactionmode |
|
|
24
0
|
|
|
A B · C#Excel自动调整列避免长文本时出错 1 年前 |
|
|
Megrez7 · C#ToArray转换合并为一行,导致数组元素更改 1 年前 |
|
Aycon · 在工厂方法中释放部分创建的对象的正确方法是什么? 1 年前 |
|
|
Sei · Avalonia/WPF将路由器传递到控制模板 1 年前 |