The*_*uld 6 .net garbage-collection
我们有一种情况,我们正在考虑在RAM非常低的服务器上强制进行垃圾收集(平均使用3.6/4GB).不,不幸的是,升级此服务器并不是一个真正的选择.
我们的一个服务进程(用C++间接编写(不要问...))可以使用.NET组件,然后睡10分钟.当该服务处于休眠状态时,它通常会挂在可以与其他进程共享的600MB RAM上.似乎某种方式与WSE跟踪有关,用于调试.我可以看到它在第一次COM调用.NET的下一次迭代时唤醒和GC - 然而这个过程做了一些工作,当它进入睡眠状态时,RAM使用量恢复到大约600MB ......好吧,你可以看出这是怎么回事......
问题:我正在考虑在进程进入睡眠状态之前添加垃圾收集.此框中还有其他服务正在执行与.NET相关的任务.当我在此服务进程中调用垃圾收集时,该GC是否影响该框上的所有其他.NET相关进程或仅影响请求收集的进程?我有点担心为我所关心的流程之外的流程创建某种性能问题.
jsi*_*ght 10
它只会影响调用GC的进程.
它只影响它调用的进程(但会影响进程中的所有应用程序域).但是,请注意,这不会释放内存到操作系统.如果要将内存释放到操作系统,可以采用以下方法:
private static void minimizeMemory()
{
GC.Collect(GC.MaxGeneration);
GC.WaitForPendingFinalizers();
SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle,
(UIntPtr) 0xFFFFFFFF, (UIntPtr) 0xFFFFFFFF);
}
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetProcessWorkingSetSize(IntPtr process,
UIntPtr minimumWorkingSetSize, UIntPtr maximumWorkingSetSize);
Run Code Online (Sandbox Code Playgroud)
这里最大的警告是为什么.除非你注意到内存崩溃或交换是性能瓶颈(或者你正在编写最终用户应用程序),否则没有真正的理由担心内存使用情况.强制GC可能很慢.减少堆将导致需要从VM重新分配堆.此外,.NET GC具有反应性,使用程序行为来提高其效率.通过强制收集,您不允许GC根据程序的行为进行调整,从而进一步降低性能.
我从经验中知道这一点 - 我回过头来问了这个问题,甚至提出了一个基于计时器的类,在离开高内存操作(每5分钟运行一次)后调用上面的方法.在此之后,进程工作集会自行减少很多 - 通过将其交换到磁盘.在接下来的几秒钟内,它将回读最常用的部件,几分钟后(当任务再次运行时),它将再次进行一堆分配.时间(甚至不是剖析)该过程表明,对于该任务,在从OS分配VM期间,大约有0.2秒(!)减速.
你应该明智地找到一个分析器,看看为什么对象没有被有效地垃圾收集.可能是他们在gen2中不必要地结束了,你可以重构它以允许它更快地摆脱对象.
您还可以尝试确保.NET部件与垃圾收集器的服务器版本一起运行,默认情况下是工作站版本,这更喜欢保持进程处于活动状态而不是运行GC(即它已经过调整以保持UI响应).服务器版本更具侵略性并且运行并行GC,每个核心也有一个.
将以下内容添加到app.config:
<Configuration>
<runtime>
<gcServer enabled=“true“ />
</runtime>
</Configuration>
Run Code Online (Sandbox Code Playgroud)
链接到更多信息
| 归档时间: |
|
| 查看次数: |
1305 次 |
| 最近记录: |