2016-07-12 6 views
0

Я использую этот SimpleSwingBrowser. Он потребляет слишком много памяти и не освобождает эту память. Я постоянно вижу потребляемую память в диспетчере задач и увеличивается до 500 МБ при посещении только трех сайтов и постоянно растет.Как освободить потребляемую память webEngine в браузере javaFX

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

import javafx.application.Platform; 
    import javafx.beans.value.ChangeListener; 
    import javafx.beans.value.ObservableValue; 
    import javafx.embed.swing.JFXPanel; 
    import javafx.event.EventHandler; 
    import javafx.scene.Scene; 
    import javafx.scene.web.WebEngine; 
    import javafx.scene.web.WebEvent; 
    import javafx.scene.web.WebView; 

    import javax.swing.*; 
    import java.awt.*; 
    import java.awt.event.*; 
    import java.net.MalformedURLException; 
    import java.net.URL; 

    import static javafx.concurrent.Worker.State.FAILED; 

    public class SimpleSwingBrowser extends JFrame { 

    private final JFXPanel jfxPanel = new JFXPanel(); 
    private WebEngine engine; 

    private final JPanel panel = new JPanel(new BorderLayout()); 
    private final JLabel lblStatus = new JLabel(); 


    private final JButton btnGo = new JButton("Go"); 
    private final JTextField txtURL = new JTextField(); 
    private final JProgressBar progressBar = new JProgressBar(); 

    public SimpleSwingBrowser() { 
     super(); 
     initComponents(); 
    } 


    private void initComponents() { 
     createScene(); 

     ActionListener al = new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent e) { 
       loadURL(txtURL.getText()); 
      } 
     }; 

     btnGo.addActionListener(al); 
     txtURL.addActionListener(al); 

     progressBar.setPreferredSize(new Dimension(150, 18)); 
     progressBar.setStringPainted(true); 

     JPanel topBar = new JPanel(new BorderLayout(5, 0)); 
     topBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); 
     topBar.add(txtURL, BorderLayout.CENTER); 
     topBar.add(btnGo, BorderLayout.EAST); 

     JPanel statusBar = new JPanel(new BorderLayout(5, 0)); 
     statusBar.setBorder(BorderFactory.createEmptyBorder(3, 5, 3, 5)); 
     statusBar.add(lblStatus, BorderLayout.CENTER); 
     statusBar.add(progressBar, BorderLayout.EAST); 

     panel.add(topBar, BorderLayout.NORTH); 
     panel.add(jfxPanel, BorderLayout.CENTER); 
     panel.add(statusBar, BorderLayout.SOUTH); 

     getContentPane().add(panel); 

     setPreferredSize(new Dimension(1024, 600)); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     pack(); 

    } 

    private void createScene() { 

     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 

       WebView view = new WebView(); 
       engine = view.getEngine(); 

       engine.titleProperty().addListener(new ChangeListener<String>() { 
        @Override 
        public void changed(ObservableValue<? extends String> observable, String oldValue, final String newValue) { 
         SwingUtilities.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           SimpleSwingBrowser.this.setTitle(newValue); 
          } 
         }); 
        } 
       }); 

       engine.setOnStatusChanged(new EventHandler<WebEvent<String>>() { 
        @Override 
        public void handle(final WebEvent<String> event) { 
         SwingUtilities.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           lblStatus.setText(event.getData()); 
          } 
         }); 
        } 
       }); 

       engine.locationProperty().addListener(new ChangeListener<String>() { 
        @Override 
        public void changed(ObservableValue<? extends String> ov, String oldValue, final String newValue) { 
         SwingUtilities.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           txtURL.setText(newValue); 
          } 
         }); 
        } 
       }); 

       engine.getLoadWorker().workDoneProperty().addListener(new ChangeListener<Number>() { 
        @Override 
        public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, final Number newValue) { 
         SwingUtilities.invokeLater(new Runnable() { 
          @Override 
          public void run() { 
           progressBar.setValue(newValue.intValue()); 
          } 
         }); 
        } 
       }); 

       engine.getLoadWorker() 
         .exceptionProperty() 
         .addListener(new ChangeListener<Throwable>() { 

          public void changed(ObservableValue<? extends Throwable> o, Throwable old, final Throwable value) { 
           if (engine.getLoadWorker().getState() == FAILED) { 
            SwingUtilities.invokeLater(new Runnable() { 
             @Override public void run() { 
              JOptionPane.showMessageDialog(
                panel, 
                (value != null) ? 
                engine.getLocation() + "\n" + value.getMessage() : 
                engine.getLocation() + "\nUnexpected error.", 
                "Loading error...", 
                JOptionPane.ERROR_MESSAGE); 
             } 
            }); 
           } 
          } 
         }); 

       jfxPanel.setScene(new Scene(view)); 
      } 
     }); 
    } 

    public void loadURL(final String url) { 
     Platform.runLater(new Runnable() { 
      @Override 
      public void run() { 
       String tmp = toURL(url); 

       if (tmp == null) { 
        tmp = toURL("http://" + url); 
       } 

       engine.load(tmp); 
      } 
     }); 
    } 

    private static String toURL(String str) { 
     try { 
      return new URL(str).toExternalForm(); 
     } catch (MalformedURLException exception) { 
       return null; 
     } 
    } 



    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      public void run() { 
       SimpleSwingBrowser browser = new SimpleSwingBrowser(); 
       browser.setVisible(true); 
       browser.loadURL("http://oracle.com"); 
      }  
     }); 
    } 
} 

ответ

0

Это фактическая «проблема-рода ограничение» с Java.Even, если вы звоните System.gc(), который не рекомендуется, он не уверен, что сборщик мусора освободить память. One way is to setObject до null, поэтому он отмечен как очищаемый.

Даже если у вас было тонны элементов, и вы их удаляете, вы можете увидеть, что потребление плунжера одинаково. Иногда Java использует по умолчанию больше памяти, поэтому ваше приложение не будет отставать.

У вас есть сборщик мусора, который выполняет работу и создает новые объекты со стратегией. Если объект остался too long («отметьте, что Java8 отличается permgen не существует») у вас есть вероятность, что он никогда не будет собран из gc. Иногда может потребоваться 1 минута для выпуска, например, 200 MiB памяти.

Некоторые элементы, такие как WebViewer, потребляют много оперативной памяти. Вы можете видеть то же самое для Firefox, но через некоторое время очищает его.

+0

Спасибо за ваш ответ. –

+0

@rajat agarwal Мне было любопытно об этом с давних времен :) – GOXR3PLUS

+0

@GoXrPlus С удовольствием узнаем об этом :). Таким образом, есть способ решить эту проблему без использования нулевого объекта. Потому что использование нулевого объекта создает множество проблем. Это похоже на загрузку нового веб-движка. –

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

  • Нет связанных вопросов^_^