爬虫工作数小时后出现 Jsoup Out of memory 错误

Jsoup Out of memory error after the crawler has worked for hours

嗯,我用 Jsoup 1.8.1 做了一个爬虫。昨天我 运行 它,5-6 小时后它给出了内存不足异常。今天也发生了同样的事情。它工作了几个小时,抓取了 5000 多页,然后给出了内存不足异常。

doc = Jsoup.connect(page_url).timeout(10*1000).get();



Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.Arrays.copyOfRange(Arrays.java:2694)
at java.lang.String.<init>(String.java:203)
at org.jsoup.parser.CharacterReader.consumeToAny(CharacterReader.java:133)
at org.jsoup.parser.TokeniserState.read(TokeniserState.java:779)
at org.jsoup.parser.Tokeniser.read(Tokeniser.java:42)
at org.jsoup.parser.TreeBuilder.runParser(TreeBuilder.java:47)
at org.jsoup.parser.TreeBuilder.parse(TreeBuilder.java:41)
at org.jsoup.parser.HtmlTreeBuilder.parse(HtmlTreeBuilder.java:55)
at org.jsoup.parser.Parser.parseInput(Parser.java:30)
at org.jsoup.helper.DataUtil.parseByteData(DataUtil.java:115)
at org.jsoup.helper.HttpConnection$Response.parse(HttpConnection.java:532)
at org.jsoup.helper.HttpConnection.get(HttpConnection.java:171)
at classes.CrawlPages.pageInfo(CrawlPages.java:88)
at classes.CrawlPages.processController(CrawlPages.java:67)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.processController(CrawlPages.java:70)
at classes.CrawlPages.readSeed(CrawlPages.java:41)
at classes.StartRun.main(StartRun.java:40)

问题是,如果我再次 运行 爬虫,它能够再次轻松地爬取相同的页面。我的情况是异常不依赖于页面。页面大小也低于 200KB。

这是因为我使用的递归函数还是一些我不知道的内存?

好的,在 Eclipse Memory Analyzer 工具的帮助下,我找到了 java.lang.OutOfMemoryError 的原因:Java 堆 space。它表明数据库连接对象正在增长。我使用了静态 Connection 变量,并希望它能节省内存,但它没有发生。所以现在我要删除对所有未使用的数据库连接的引用。 虽然我仍然没有以正确的方式做到这一点,但至少它现在没有内存不足。

我找到了可能解决您的部分问题的解决方法。

就我而言,在抓取大约 100Kwww 之后,我曾经遇到内存问题、java 堆问题等等,程序总是停止。我一次又一次地检查代码,遵循最佳实践,关闭连接,最后我放弃了,并从 bash 那里得到了一些帮助。

基本上我编写了一个 bash 运行 java -jar myscraper.jar 的脚本,以便仅报废 100Kwww。之后,当 Java 完全报废第一组 100Kwww 时,bash 脚本开始下一组,依此类推。

也许不是最好的,但对我来说,这是在没有内存问题的情况下每天报废 4Mwww 的唯一方法。