Почему этот объект env продолжает расти в размере?

Я работаю над веб-сканером уже некоторое время, идея проста, у меня есть таблица SQL, содержащая список веб-сайтов, у меня много потоков, которые выбирают первый веб-сайт из таблицы и удаляют его, а затем сканируют (в куча как манера).

Код слишком длинный, поэтому я попытаюсь удалить некоторые его части:

 while(true){
    if(!stopped){  
        System.gc();

        Statement stmt;
        String scanned = "scanned";
        if (!scan)scanned = "crawled";
        Connection connection = null;
            try {
            connection = Utils.getConnection();
            } catch (Exception e1) {

            connection.close();
            e1.printStackTrace();
            }
            String name;
            stmt = connection.createStatement();
            ResultSet rs = null;
            boolean next;
            do {
            rs = stmt.executeQuery("select url from websites where "+scanned+" = -1");
            next = rs.next();
            } while (next && Utils.inBlackList(rs.getString(1)));


            if(next){
            name = rs.getString(1);
            stmt.executeUpdate("UPDATE websites SET "+scanned+" = 1 where url = '"+Utils.stripDomainName(name)+"'");
            String backup_name = name;
            name = Utils.checkUrl(name);
            System.out.println(scanned + " of the website :  " + name +" just started by the Thread : " + num);

            // And here is the important part, I think

            CrawlConfig config = new CrawlConfig();
            String ts = Utils.getTime();
            SecureRandom random = new SecureRandom();
            String SessionId = new BigInteger(130, random).toString(32);
            String crawlStorageFolder = "tmp/temp_storageadmin"+SessionId;
            config.setCrawlStorageFolder(crawlStorageFolder);

            config.setPolitenessDelay(Main.POLITENESS_DELAY);
            config.setMaxDepthOfCrawling(Main.MAX_DEPTH_OF_CRAWLING);
            config.setMaxPagesToFetch(Main.MAX_PAGES_TO_FETCH);
            config.setResumableCrawling(Main.RESUMABLE_CRAWLING);
            int numberOfCrawlers = Main.NUMBER_OF_CRAWLERS;
            PageFetcher pageFetcher = new PageFetcher(config);
            RobotstxtConfig robotstxtConfig = new RobotstxtConfig();
            RobotstxtServer robotstxtServer = new RobotstxtServer(robotstxtConfig, pageFetcher);

            try {
                  controller = new CrawlerController(config, pageFetcher, robotstxtServer);
                  controller.addSeed(name);
                  controller.setSeeed(name);
                  controller.setTimestamp(ts);
                  controller.setSessiiid("admin"+num+scan);

                  //Main.crawls.addCrawl("admin"+num+scan, new Crawl(name,"admin"+num+scan,ts));
                 stmt.executeUpdate("DELETE FROM tempCrawl WHERE SessionID = '"+"admin"+num+scan+"'");
                  if (!scan){
                     // Main.crawls.getCrawl("admin"+num+scan).setCrawl(true);

                     stmt.executeUpdate("INSERT INTO tempCrawl (SessionID, url, ts, done, crawledpages, misspelled, english, proper, scan, crawl )"
                        + " VALUES ( '"+"admin"+num+scan+"', '"+name+"', '"+ts+"', false, 0, 0, true, false, "+false+" , "+true+"  )");
                  }else{
                      //Main.crawls.getCrawl("admin"+num+scan).setScan(true);

                     stmt.executeUpdate("INSERT INTO tempCrawl (SessionID, url, ts, done, crawledpages, misspelled, english, proper, scan, crawl )"
                        + " VALUES ( '"+"admin"+num+scan+"', '"+name+"', '"+ts+"', false, 0, 0, true, false, "+true+" , "+false+"  )");
                  }
                  connection.close();
                  controller.start_auto(Crawler.class, numberOfCrawlers, false, scan,num);

            } catch(Exception e){
                      rs.close();
                      connection.close();
                  e.printStackTrace();
              }
            }else{
               rs.close();
               connection.close();
            }  






        //CrawlerController.start_auto(scan, num);

        if (stopping){
        stopped = true;
        stopping = false;
        }
    }}
    } catch (Exception e) {
        e.printStackTrace();
    }

Как видите, каждый раз я создаю crawlerController, сканирую веб-сайт и так далее.

Проблема в том, что размер кучи памяти jvm значительно увеличивается. После профилирования приложения с использованием профилировщика Java yourKit я обнаружил утечку памяти в следующих строках кода:

скриншот профилирования yourKit

Теперь это точная строка, с которой начинается утечка памяти, эта переменная env, кажется, занимает слишком много места и продолжает увеличиваться после каждой операции, тогда как операции независимы.

    Environment env = new Environment(envHome, envConfig);

Я действительно не знаю, что делает эта переменная, и как я мог это исправить, еще одна вещь, я изменил исходный код crawlController, я подумал, что это может быть актуально.

1 ответ

Предполагая, что вы используете crawler4j как ползучий каркас.

Каждый раз, когда вы создаете crawl controller вы создаете новый экземпляр frontier, который совместно используется потоками искателя для управления очередью URL-адресов для сканирования. Кроме того, создается так называемый docIdServer, который отвечает за управление, если входящий URL-адрес (например, веб-сайт) уже был обработан в этом обходе.

это frontier и docIdServer основаны на базе данных в памяти, в которой среда отвечает за кэширование, блокировку, ведение журнала и транзакции. По этой причине эта переменная будет расти со временем.

Если вы установите возобновляемое сканирование на trueбаза данных будет работать в файловом режиме и там будет расти медленнее.

Другие вопросы по тегам