2016-07-12 6 views
0

Ich benutze diesen SimpleSwingBrowser. Es verbraucht zu viel Speicher und gibt diesen Speicher nicht frei. Ich sehe kontinuierlich den konsumierten Speicher im Task-Manager und es erhöht sich auf 500 MB beim Besuch von nur drei Sites und es steigt kontinuierlich.Wie man den verbrauchten Speicher durch die webEngine im javaFX Browser freigibt

Also ich möchte den gesamten Speicher freigeben, wenn der Browser auf die nächste Seite wechseln. Bedeutet, dass der gesamte von der vorherigen Seite belegte Speicher entsorgt oder gelöscht werden muss.

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"); 
      }  
     }); 
    } 
} 

Antwort

0

Das ist eine ‚Problem-Art von Einschränkung‘ mit Java.Even wenn Sie System.gc() nennen, die nicht empfohlen wird, ist es nicht sicher, dass der Garbage Collector Speicher freigeben wird. One way is to set die Object zu null, so ist es markiert, um gelöscht zu werden.

Auch wenn Sie eine Menge Elemente hatten und Sie sie löschen, können Sie sehen, dass der RAM-Verbrauch derselbe ist. Manchmal verwendet Java standardmäßig mehr Speicher, sodass Ihre App nicht verzögert wird.

Sie haben warten Müllsammler tun die Arbeit und erstellen neue Objekte mit Strategie. Wenn ein Objekt geblieben ist too long ("erwähnen, dass Java8 ist anders permgen nicht existiert") haben Sie eine Möglichkeit, dass es nie von GC gesammelt wurde. Manchmal kann es 1 Minute dauern, um zum Beispiel 200 MiB des Speichers freizugeben.

Einige Elemente wie WebViewer verbrauchen viel RAM.Sie können das gleiche für Firefox sehen, aber es löscht es nach einer Weile.

+0

Danke für Ihre Antwort. –

+0

@rajat agarwal ich bin seit einer langen Zeit seit jetzt neugierig geworden :) – GOXR3PLUS

+0

@GoXrPlus Ich freue mich darüber zu hören :). Es gibt also eine Möglichkeit, dieses Problem zu lösen, ohne das Null-Objekt zu verwenden. Weil die Verwendung von Null-Objekten viele Probleme verursacht. Es ist wie das Laden der neuen Web-Engine. –

Verwandte Themen