CrawlScript / WebCollector

WebCollector is an open source web crawler framework based on Java.It provides some simple interfaces for crawling the Web,you can setup a multi-threaded web crawler in less than 5 minutes.
https://github.com/CrawlScript/WebCollector
GNU General Public License v3.0
3.07k stars 1.45k forks source link

depth过大导致内存溢出 #78

Closed carryxyh closed 6 years ago

carryxyh commented 6 years ago

Generator使用BerkeleyGenerator时,depth参数过大导致内存溢出。 看了一下会循环调用fetcher.fetchAll,这里面会创建多个QueueFeeder,这个线程run方法中: generator.next() 最终会跑到: if (cursor.getNext(key, value, LockMode.DEFAULT) == OperationStatus.SUCCESS) { CrawlDatum datum = BerkeleyDBUtils.createCrawlDatum(key, value); return datum; }else{ return null; } cursor.getNext(key, value, LockMode.DEFAULT)这里会最终调用EnvironmentImpl.addToCompressorQueue :

    /*
     * May be called by the cleaner on its last cycle, after the compressor
     * is shut down.
     */
    if (inCompressor != null) {
        inCompressor.addBinToQueue(bin, doWakeup);
    }

这里的BIN的id是BerkeleyGenerator中的:protected DatabaseEntry key = new DatabaseEntry(); 每次都是new出来的

最终导致的结果: LN数量特别多,1G内存中占用了将近700MB,加上BIN的数量也不少,内存溢出了。

解决方案也没有特别好的办法,只能start时根据depth给一个warn,太大了提醒用户可能导致的问题。

hujunxianligong commented 6 years ago

不好意思,前面比较忙没有看Github。感谢您宝贵的意见,我会看下怎么解决!

carryxyh commented 6 years ago

你好,我还提了一个PR,新增了一个WARN级别的log,用来在depth超过阈值(10)时给用户一个提醒,目前能想到的解决办法就是这样。在提醒了使用方的情况下,如果使用方依然要抓取深度很深的内容时,需要用户自己去调整JVM的内存 这个细节也可以写到readme提醒一下

hujunxianligong commented 6 years ago

我先尝试处理一下这个问题,有可能打算把伯克利DB整个换掉了,我自己用的时候depth较大的场景还是蛮多的,感觉可能是需要depth较大,且topN不限制或者较高时会出现这个问题。感谢感谢!

carryxyh commented 6 years ago

OK!

mdzz9527 commented 6 years ago

Exception when updating db java.lang.IllegalStateException: Can't call Database.put Database was closed.请教一下,这个问题。大佬

carryxyh commented 6 years ago

@Mr-Malone 另外开一个issue吧。这个我关掉了

mdzz9527 commented 6 years ago

怎么关了?

carryxyh commented 6 years ago

另开一个issue吧。你的应该不是这个问题吧?

mdzz9527 commented 6 years ago

嗯。开过了,谢谢