【问题标题】:Clean memory after using a large list of data in WCF Service在 WCF 服务中使用大量数据后清理内存
【发布时间】:2013-02-08 23:36:38
【问题描述】:

我有一个 WCF 客户端,我连接到托管在 Windows 服务中的 WCF 服务器。在服务中,我从安全事件日志中读取了最后一天的条目。然后我解析条目并创建我自己的List<Data>,我将其返回到我的 WCF 客户端以在 DataGrid 中显示它。问题是,在安全事件日志中,我有 30000 个条目,在解析每个条目后,我创建了 30000 个 Data 类型的新对象。此类型是一个具有 15 个字符串属性的类,其中包含来自事件日志的消息的详细信息。整个过程结束后,Windows 服务的内存使用量上升了 60-70MB。一旦我向客户端发送了这么多数据集,如何才能将 Windows 服务使用的内存从 70-80MB 降低到默认的 10MB?

这是我的代码:

public List<Data> GetConnections()
{        
   var eventLog = new EventLog("Security");
   var fromDate = DateTime.Now.AddDays(-1);
   var entries = (from EventLogEntry e in eventLog.Entries
                   where (e.InstanceId == m_EventNumber) && e.TimeGenerated >= fromDate orderby e.TimeGenerated
                   select e).ToList()
                            .OrderByDescending(x => x.TimeGenerated);

   var items = new List<Data>();
   foreach(var item in entries)
   {
      var nData = ParseMessage(item.Message);
      if (nData != null)
          items.Add(ruleData);
   }
   return items;
}

【问题讨论】:

  • attribute设置的服务SessionMode的设置是什么?
  • SessionMode = SessionMode.Required
  • 好的,ServiceBehaviorAttribute.InstanceContextMode?
  • InstanceContextMode=InstanceContextMode.Single
  • 尝试使用这个参数。单身意味着单身人士。 PerCall 将销毁服务对象及其引用的所有实例。什么可以获得一些 GC 性能。买也不一定。

标签: c# windows wcf memory-management event-log


【解决方案1】:

更高效的代码:只有一个循环而不是两个循环,GC 收集的对象更少。

var q = from EventLogEntry e in eventLog.Entries
        where (e.InstanceId == m_EventNumber) && e.TimeGenerated >= fromDate orderby e.TimeGenerated
        order by e.TimeGenerated desc
        let r = ParseMessage(e.Message)
        where r != null
        select r;

return new List<Data>(q);

【讨论】:

  • ParseMessage 显然可以返回 null,这在结果列表中是不需要的。
  • 感谢您的改进。它提高了速度。
【解决方案2】:

您的内存消耗是否会随着每次调用服务而不断增加?如果每分钟调用一次服务,一小时后是否有 60*70MB 的内存使用?如果没有,那么您可能没有内存泄漏。您无需采取任何行动。

【讨论】:

  • 内存随着每次调用而略有增加。我找到了一种解决方法。在进行查询之前,我调用: GC.GetTotalMemory(true);这将强制对旧数据进行垃圾收集。此外,1 分钟后,我调用相同的 GC.GetTotalMemory(true);并且服务的内存回到 10MB。正如我所看到的,没有内存泄漏,但是对象在使用后的很长一段时间内都可以驻留在内存中。非常感谢你。我不能让 GC 自动完成它的工作,因为如果我的用户长时间在任务管理器中看到 100MB 的服务,他们不会喜欢这样。
  • 教导您的用户,而不是通过强制进行不必要的垃圾回收来破坏您的应用程序。
猜你喜欢
  • 2012-11-22
  • 2012-01-03
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
  • 2010-10-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多