java.lang.OutOfMemoryError:爬网时超出了GC开销限制

时间:2017-03-28 08:56:28

标签: java out-of-memory

我正在尝试抓取网站并插入我在散列集中找到的href,插入650链接后我得到异常java.lang.OutOfMemoryError:超出了GC开销限制。 我怎么能让它工作?

我将代码放在下面:

public void getPageLinks(String URL, String otherlinksSelector ) {
    if (!links.contains(URL)) {
        try {
            Document document = Jsoup.connect(URL).userAgent("Mozilla").get();
            Elements otherLinks = document.select(otherlinksSelector); 
            for (Element page : otherLinks) {
                if (links.add(URL)) {
                    System.out.println(URL);
                }
                getPageLinks(page.attr("abs:href"),otherlinksSelector);
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

2 个答案:

答案 0 :(得分:0)

首先是formost,一个只管理内存中所有URL的爬虫必须相当挑剔,要保留哪些URL以及丢弃哪些URL作为内存是爬虫的限制因素,除非你将这些信息外化或者拥有相当无限量的集群可用的内存。在OOMing之前的650个URL虽然是非常少量的TBH。例外情况至少表明,garbate收集器在尝试释放内存时花费了太多时间,这表明最大可用内存通常不够。

了解填充内存的一种方法是使用分析器并以特定时间间隔进行堆转储,然后检查转储是否有可用对象以及它们占用了多少内存以及哪些对象引用它们。此外,尝试在获取堆之前强制GC以了解内存中的内容。通过这种方式,您可能会看到阻止收集器释放更多内存的原因。

接下来,有一些科学论文(DRUMVEUNIQ,......)研究持久存在的URL,包括以高效的方式进行独特检查。在工作中有几个开源实现,虽然其中大部分还没有完成(包括我的方法); DRUMS可能是最重要的方法。

答案 1 :(得分:-1)

您可以继续写入文件的链接,而不是将其保留在内存中。 这样你内存中的数据就会减少。如果您想要解析过去发现的其他链接,可以从同一个文件中读取。