2015-07-27 5 views
0

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

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

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 значительно увеличивается. После профилирования приложения с использованием YourKit Java профилировщика Я обнаружил утечку памяти в следующих строках кода:

yourKit profiling screenshot

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

Environment env = new Environment(envHome, envConfig); 

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

+0

крошечный совет: вы должны использовать частные методы для упорядочивания кода в цикле для большей ясности. Это поможет вам и другим программистам, которые могут захотеть понять или сохранить ваш код :) – MWiesner

+0

Спасибо! Я просто имею плохую привычку записывать все это, а затем организую его только после того, как он работает, как я сказал, плохая привычка. –

ответ

1

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

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

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

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

Смежные вопросы