代码之家  ›  专栏  ›  技术社区  ›  Mahdi Amrollahi

如何释放虚拟内存?

  •  2
  • Mahdi Amrollahi  · 技术社区  · 14 年前

    我有一个爬虫应用程序(带有C),可以从Web下载页面。 应用程序需要更多的虚拟内存, 即使我处理每件物品甚至使用 GC.Collect() .

    这个,有10个线程,每个线程都有一个下载页面的套接字。 在每一个线程中,我都有一个 byte[] buffer 存储页面内容,并且 安 string str_content 我存储在其中,页面内容以字符串形式存储。 我有一个 Sytem.Timer 每3秒一次,如果每根线都停止, 分配新线程并启动它。

    我使用处置方法,甚至使用 GC.Collect() 在我的申请中,但在3小时内我的申请需要 在虚拟内存上为500 MB(在Process Explorer中,在专用字节上为500 MB)。然后我的系统 将挂起,我应该重新启动电脑。

    1. 如果我把我的 byte[] string 为零?

    2. 我有没有办法释放虚拟内存?

    谢谢。

    3 回复  |  直到 14 年前
        1
  •  6
  •   Mitchel Sellers    14 年前

    首先,无论如何,您不应该调用gc.collect(),因为这是一个昂贵的调用,而且不应该是必需的。

    如果你看到了成长,你还在打电话 gc.collect() 您的资源仍然有引用,因此无法收集它们。

    我将开始查看您的代码,并确保所有对象都声明在适当的范围内,您使用的是using语句语法,以确保实现IDisposable的项被正确清理,并对代码进行全面检查。

    下一步是使用一个工具,比如AntsProfiler或者类似的工具,查看内存中实际存储的内容。

        2
  •  3
  •   JustLoren    14 年前

    要想知道内存泄漏在哪里,需要对代码进行研究。很可能是在您正在绑定的事件中(手动或自动),这些事件导致明显超出范围的对象无法得到正确的处理。

        3
  •  3
  •   Edwin Buck    14 年前

    在C++(和Java)中,只要有对对象的引用,程序环境就假定您仍在使用该对象。调用空闲内存将只释放未使用的对象。关键是停止使用对象。

    很有可能你有如下的东西:

    Object mine = new Object();
    

    关键是你也需要这样的东西:

    mine = null;
    

    表示“我的”物体不再被使用。通常,这些问题不会发生在这样的代码块中,因为一旦离开该块,变量就不再可访问:

    public void process() {
      Object mine = new Object();
    }
    

    通常,这些问题发生在这样的代码块中,因为集合会随着时间累积对象:

    static List tasks = new ArrayList();
    
    public void process(String item) {
      tasks.add(item);
    }
    

    关键是没有相应的 tasks.remove(item) 该列表将永远保存对项目的引用,这将妨碍垃圾收集工作。