代码之家  ›  专栏  ›  技术社区  ›  Dan McClain

在处理大量文本时防止内存问题

  •  8
  • Dan McClain  · 技术社区  · 15 年前

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

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

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

    前几天,我在我的小组所做的一个更大的项目上运行它,我的程序突然出现在我身上,因为内存中加载了太多的源代码。目前这是一个棘手的问题,但我希望将来能够处理这个问题。

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

    我正在考虑加载代码,对文件进行初始处理,然后将结果序列化到磁盘,这样当我需要再次访问这些结果时,就不必再执行处理原始代码的过程。这有道理吗?或者序列化/反序列化比再次处理代码更昂贵?

    我希望在解决这个问题时保持合理的性能水平。大多数情况下,源代码可以毫无问题地放入内存中,所以当内存不足时,是否有一种方法可以只“分页”我的信息?有没有一种方法可以告诉我的应用程序何时内存不足?

    更新 : 问题不在于一个文件填满了内存,而是它的所有文件一次填满了内存。我目前的想法是当我处理磁盘驱动器时将其旋转。

    4 回复  |  直到 15 年前
        1
  •  3
  •   mfeingold    15 年前

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

    当您解析源代码时,您可能会将其拆分为某些子字符串-标记或您所调用的对象。如果您的令牌结合了整个源代码,则会使内存消耗增加一倍。根据处理的复杂性,您可以做的多裂器甚至更大。 我在这里的第一步是更详细地了解如何使用字符串,并找到一种优化它的方法——即在第一次传递之后丢弃原始字符串,压缩空白,或者使用原始字符串的索引(指针),而不是实际的子字符串——这里有很多有用的技术。

    如果这一切都不起作用的话,我会用磁盘来回交换它们。

        2
  •  1
  •   Shiraz Bhaiji    15 年前

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

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

    您还应该检查是否正确地处理了对象。由于内存中存在对象的旧副本,您是否有内存问题?

        3
  •  0
  •   leppie    15 年前

    使用带有sos的windbg来查看字符串引用中包含的内容(或导致极端内存使用的原因)。

        4
  •  0
  •   Matt Wrock    15 年前

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

    当然,这将取决于代码文件的大小。我的档案相当小。