【问题标题】:Preventing Memory issues when handling large amounts of text处理大量文本时防止内存问题
【发布时间】:2010-11-28 11:36:39
【问题描述】:

我编写了一个程序,它分析项目的源代码并根据代码报告各种问题和指标。

为了分析源代码,我加载了项目目录结构中存在的代码文件并从内存中分析代码。代码在传递给其他方法进行进一步分析之前会经过大量处理。

代码在处理时被传递给几个类。

前几天,我在我小组的一个较大项目上运行它,但由于加载到内存中的源代码过多,我的程序崩溃了。目前这是一个极端情况,但我希望将来能够处理这个问题。

避免内存问题的最佳方法是什么?

我正在考虑加载代码,对文件进行初始处理,然后将结果序列化到磁盘,这样当我需要再次访问它们时,我就不必经过处理原始数据的过程再次编码。这有意义吗?还是序列化/反序列化比再次处理代码更昂贵?

我希望在解决此问题的同时保持合理的性能水平。大多数时候,源代码会毫无问题地放入内存中,那么当我内存不足时,有没有办法只“分页”我的信息?有没有办法判断我的应用程序何时内存不足?

更新: 问题不在于单个文件填满内存,而是内存中的所有文件一次填满内存。我目前的想法是在处理它们时关闭磁盘驱动器

【问题讨论】:

  • 我会采用序列化方法。但是看看 FindBug 的源代码。他们做了类似的事情,也许他们已经解决了这个问题:findbugs.sourceforge.net/downloads.html
  • 内存大小与磁盘文件大小的比例是多少?
  • 您提到在类之间传递字符串。根据您处理字符串的方式,可能正在制作一些副本,因此您使用的内存超出了您的需要。我不确切知道 C# 如何处理传递字符串,但如果它复制它们,那么这可能是问题。

标签: c# memory-management


【解决方案1】:

1.6GB 仍然是可管理的,它本身不会导致内存问题。低效的字符串操作可能会做到这一点。

当您解析源代码时,您可能会将其拆分为某些子字符串 - 标记或您所称的任何内容。如果您的代币结合了整个源代码,那么那里的内存消耗就会增加一倍。根据您执行的处理的复杂性,乘数可能更大。 我在这里的第一步是仔细研究如何使用字符串并找到优化它的方法 - 即在第一次通过后丢弃原始字符串,压缩空格或使用指向原始字符串的索引(指针)而不是实际的子字符串 - 这里有许多有用的技术。

如果这些都无济于事,我会求助于在磁盘之间来回交换它们

【讨论】:

  • 这是有道理的,因为我有各种可用的文件状态,可能会将大小增加三倍
【解决方案2】:

如果问题是代码的单个副本导致您填满可用内存,那么至少有两个选项。

  • 序列化到磁盘
  • 压缩内存中的文件。如果您有大量 CPU,则可以更快地在内存中压缩和解压缩信息,而不是缓存到磁盘。

您还应该检查您是否正确处理了物品。您是否因对象的旧副本在内存中而存在内存问题?

【讨论】:

    【解决方案3】:

    使用带有 SOS 的 WinDbg 来查看字符串引用上的内容(或导致内存使用量过大的原因)。

    【讨论】:

    • 这与我正在分析的文件夹是 1.6GB 的事实有关(包括编译的二进制文件,但我没有加载那些,代码量仍然很大)
    【解决方案4】:

    序列化/反序列化听起来是个不错的策略。我已经做了很多,而且速度非常快。事实上,我有一个应用程序可以从数据库中实例化对象,然后将它们序列化到我的 Web 节点的硬盘上。自从我对它进行基准测试已经有一段时间了,但是当我进行负载测试时,它每秒序列化数百次,并且可能超过 1k。

    当然,这取决于您的代码文件的大小。我的文件很小。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-03
      • 2014-05-14
      • 2011-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-19
      • 1970-01-01
      相关资源
      最近更新 更多